package com.cq.hd.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cq.hd.common.constant.Constant;
import com.cq.hd.common.constant.MsgConstant;
import com.cq.hd.common.constant.OrderNoteConstant;
import com.cq.hd.common.entity.hf.HfJsPay;
import com.cq.hd.common.entity.hf.HfTradeAccountPay;
import com.cq.hd.common.entity.hf.HfTradeQuery;
import com.cq.hd.common.entity.hf.HfTradeRefund;
import com.cq.hd.common.entity.mq.NotifyMsgSendDto;
import com.cq.hd.common.enums.ResponseEnums;
import com.cq.hd.common.enums.biz.*;
import com.cq.hd.common.exception.BusinessException;
import com.cq.hd.common.pagination.Page;
import com.cq.hd.common.response.Throw;
import com.cq.hd.common.utils.*;
import com.cq.hd.member.api.*;
import com.cq.hd.member.api.dto.*;
import com.cq.hd.member.api.vo.*;
import com.cq.hd.order.api.TbMonthSettleBillWithdrawalApi;
import com.cq.hd.order.api.dto.*;
import com.cq.hd.order.api.pft.PftOrderCallBackParam;
import com.cq.hd.order.api.pft.PftOrderSubmitResult;
import com.cq.hd.order.api.pft.PftOrderTicketParam;
import com.cq.hd.order.api.vo.*;
import com.cq.hd.order.config.HDFinancialAccountProperties;
import com.cq.hd.order.config.LockUtils;
import com.cq.hd.order.config.WxPubConfig;
import com.cq.hd.order.factory.OrderFactory;
import com.cq.hd.order.factory.orderSelect.OrderSelectFactory;
import com.cq.hd.order.factory.orderSettle.OrderSettleBillFactory;
import com.cq.hd.order.mapper.*;
import com.cq.hd.order.mq.provider.NotifyMsgProvider;
import com.cq.hd.order.mq.provider.OrderDelayMsgProvider;
import com.cq.hd.order.mq.provider.OrderRefundMsgProvider;
import com.cq.hd.order.mq.provider.OrderVerifyMsgProvider;
import com.cq.hd.order.param.AgentActiveCommissionParam;
import com.cq.hd.order.param.CancelWaitPayOrVerifyOrderParam;
import com.cq.hd.order.param.OrderStateUpdateParam;
import com.cq.hd.order.param.PaySuccessOrderParam;
import com.cq.hd.order.po.*;
import com.cq.hd.order.render.OrderBuilder;
import com.cq.hd.order.render.OrderContext;
import com.cq.hd.order.service.*;
import com.cq.hd.order.utils.RegexUtil;
import com.cq.hd.product.api.TbActiveApi;
import com.cq.hd.product.api.TbActiveRedPacketBillApi;
import com.cq.hd.product.api.TbActiveStepPriceApi;
import com.cq.hd.product.api.dto.ActiveAddStockDto;
import com.cq.hd.product.api.dto.ActiveDto;
import com.cq.hd.product.api.dto.ActiveGoodsSonDto;
import com.cq.hd.product.api.vo.*;
import com.cq.hd.system.api.HfApi;
import com.cq.hd.system.api.HfRequestRecordApi;
import com.cq.hd.system.api.dto.HfRequestRecordSaveDto;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author mYunYu
 * @since 2023-12-13
 */
@Slf4j
@Service
public class TbOrderServiceImpl extends ServiceImpl<TbOrderMapper, TbOrderPo> implements TbOrderService {

    @Autowired
    private TbOrderItemMapper orderItemMapper;

    @Autowired
    private TbOrderFirstRecordMapper orderFirstRecordMapper;

    @Autowired
    private TbOrderRefundMapper orderRefundMapper;

    @Autowired
    private TbOrderSettleBillMapper orderSettleBillMapper;

    @Autowired
    private TbOrderSettleBillFeeTempMapper orderSettleBillFeeTempMapper;

    @Autowired
    private TbOrderVerifyMsgMapper orderVerifyMsgMapper;

    @Autowired
    private TbOrderPayRecordMapper orderPayRecordMapper;

    @Autowired
    private TbActiveApi activeApi;

    @Autowired
    private TbActiveRedPacketBillApi activeRedPacketBillApi;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Autowired
    private TbBusinessApi businessApi;

    @Autowired
    private TbMerchantApi merchantApi;

    @Autowired
    private TbBusinessAgentApi businessAgentApi;

    @Autowired
    private TbAgentEnterApplyApi agentEnterApplyApi;

    @Autowired
    private TbBusinessMerchantApi businessMerchantApi;

    @Autowired
    private TbAppUserApi appUserApi;

    @Autowired
    private HfApi hfApi;

    @Autowired
    private TbActiveStepPriceApi activeStepPriceApi;

    @Autowired
    private HfRequestRecordApi hfRequestRecordApi;

    @Autowired
    private OrderDelayMsgProvider orderDelayMsgProvider;

    @Autowired
    private OrderRefundMsgProvider orderRefundMsgProvider;

    @Autowired
    private OrderVerifyMsgProvider orderVerifyMsgProvider;

    @Autowired
    private NotifyMsgProvider notifyMsgProvider;

    @Autowired
    private PftService pftService;

    @Autowired
    private WxPubConfig wxPubConfig;

    @Autowired
    private HDFinancialAccountProperties hdFinancialAccountProperties;

    @Autowired
    private TbOrderSettleBillItemService orderSettleBillItemService;
    @Qualifier("com.cq.hd.order.api.TbMonthSettleBillWithdrawalApi")
    @Autowired
    private TbMonthSettleBillWithdrawalApi monthSettleBillWithdrawalApi;

    @Autowired
    private TbBusinessPointsMallApi businessPointsMallApi;

    @Resource
    private OrderStepPriceCashbackService orderStepPriceCashbackService;

    @Resource
    private TbOrderRefundService orderRefundService;

    @Resource
    private OrderBuilder orderBuilder;

    @Resource
    private TbGroupBuyOrderService groupBuyOrderService;

    @Resource
    private TbOrderUnverifiedRecordService orderUnverifiedRecordService;

    @Override
    public Boolean getRedAvailableStatus(Long activeId, Long userId) {
        if (activeId == null || activeId <= 0) {
            Throw.isBusinessException("请选择活动");
        }

        if (userId == null || userId <= 0) {
            Throw.isBusinessException(ResponseEnums.USER_ACCESS_DENIED);
        }

        ActiveSimpleVo activeSimpleVo = activeApi.getSimpleVoById(activeId).unpack();
        if (activeSimpleVo == null) {
            return false;
        }

        // 判断用户是否是该商家的新用户
        OrderDto orderDto = new OrderDto();
        orderDto.setBusinessId(activeSimpleVo.getBusinessId());
        orderDto.setUserId(userId);
        orderDto.setOrderStates(Arrays.asList(OrderStateEnum.WAIT_PAY.getValue(), OrderStateEnum.WAIT_VERIFY.getValue(),
                OrderStateEnum.VERIFYING.getValue(), OrderStateEnum.FINISH.getValue(), OrderStateEnum.VERIFIED.getValue(),
                OrderStateEnum.PAYING.getValue()));
        List<OrderVo> orderVos = baseMapper.listByDto(orderDto);
        if (!CollectionUtils.isEmpty(orderVos)) {
            return false;
        }

        // 判断用户是否有领取红包,如果没有领取,返回false
        ActiveRedPacketBillPageVo activeRedPacketBillPageVo = activeRedPacketBillApi.getByActiveIdAndUserId(activeId, userId).unpack();
        if (activeRedPacketBillPageVo == null) {
            return false;
        }

        // 如果红包已过期/已使用,则不显示
        Integer state = activeRedPacketBillPageVo.getState();
        if (ActiveRedPacketStateEnum.YES_UES.getValue().equals(state) || ActiveRedPacketStateEnum.YES_VERIFY.getValue().equals(state)
                || ActiveRedPacketStateEnum.YES_EXPIRE.getValue().equals(state) || LocalDateTime.now().compareTo(activeRedPacketBillPageVo.getExpireTime()) >= 0) {
            return false;
        }

        return true;
    }

    @Override
    public Integer getActiveOrderNum(Long activeId, Long userId) {
        // 查询下单用户的待支付，支付中，待核销、核销中、已核销、已完成的该活动的订单数
        List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                .eq("active_id", activeId)
                .eq("user_id", userId)
                .in("order_state", Arrays.asList(OrderStateEnum.WAIT_PAY.getValue(),
                        OrderStateEnum.PAYING.getValue(),
                        OrderStateEnum.WAIT_VERIFY.getValue(),
                        OrderStateEnum.VERIFYING.getValue(),
                        OrderStateEnum.VERIFIED.getValue(),
                        OrderStateEnum.FINISH.getValue())));

        if (CollectionUtils.isEmpty(tbOrderPos)) {
            return 0;
        }

        return tbOrderPos.stream().mapToInt(TbOrderPo::getOrderNum).sum();
    }

    @Override
    public ActiveOrderStatisticsVo getOrderStatistics(Long businessId, Long userId, Long activeId) {
        if (businessId == null || businessId <= 0) {
            if (userId == null || userId <= 0) {
                Throw.isBusinessException(ResponseEnums.USER_ACCESS_DENIED);
            }

            // 根据userId查询商家id
            BusinessPageVo businessPageVo = businessApi.getByUserId(userId).unpack();
            if (businessPageVo == null) {
                // 如果不是商家，则返回空
                Throw.isBusinessException(ResponseEnums.BUSINESS_ACCESS_DENIED);
            }

            businessId = businessPageVo.getId();
        }

        // 有效订单=全部订单-已取消订单
        int validOrderNum = 0;
        // 订单总金额=有效订单实付金额总和
        BigDecimal totalOrderAmt = BigDecimal.ZERO;
        // 预估补贴=有效订单的营销补贴+佣金补贴+红包补贴总和
        BigDecimal estimateSubsidyAmt = BigDecimal.ZERO;

        // 查询该商户下的所有有效订单(非已取消/已关闭订单)
        List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                .eq("active_id", activeId).eq("business_id", businessId)
                .in("order_state", Arrays.asList(OrderStateEnum.WAIT_VERIFY.getValue(),
                        OrderStateEnum.VERIFYING.getValue(),
                        OrderStateEnum.VERIFIED.getValue(),
                        OrderStateEnum.FINISH.getValue())));
        if (!CollectionUtils.isEmpty(tbOrderPos)) {
            validOrderNum = tbOrderPos.size();

            List<Long> orderIds = tbOrderPos.stream().map(TbOrderPo::getId).collect(Collectors.toList());

            Map<Long, List<TbOrderItemPo>> orderItemMap = new HashMap<>();
            List<TbOrderItemPo> orderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0).in("order_id", orderIds));
            if (!CollectionUtils.isEmpty(orderItemPos)) {
                orderItemMap = orderItemPos.stream().collect(Collectors.groupingBy(TbOrderItemPo::getOrderId));
            }

            for (TbOrderPo tbOrderPo : tbOrderPos) {
                List<TbOrderItemPo> orderItemPoList = orderItemMap.get(tbOrderPo.getId());
                if (!CollectionUtils.isEmpty(orderItemPoList)) {
                    for (TbOrderItemPo tbOrderItemPo : orderItemPoList) {
                        estimateSubsidyAmt = estimateSubsidyAmt.add(tbOrderItemPo.getTotalSubsidyAmt());
                    }
                }
                totalOrderAmt = totalOrderAmt.add(tbOrderPo.getPayPrice());
            }
        }

        ActiveOrderStatisticsVo activeOrderStatisticsVo = new ActiveOrderStatisticsVo();
        activeOrderStatisticsVo.setValidOrderNum(validOrderNum);
        activeOrderStatisticsVo.setTotalOrderAmt(totalOrderAmt);
        activeOrderStatisticsVo.setEstimateSubsidyAmt(estimateSubsidyAmt);
        // 拼团成团数量
        setActiveOrderStatGroupBuyNum(activeId, activeOrderStatisticsVo);

        return activeOrderStatisticsVo;
    }

    private void setActiveOrderStatGroupBuyNum(Long activeId, ActiveOrderStatisticsVo activeOrderStatisticsVo) {
        ActiveVo activeVo = activeApi.getById(activeId).unpack();
        if (PromotionTypeEnum.GROUP_BUY.name().equals(activeVo.getPromotionType())) {
            List<GroupBuyOrderNumStatVo> groupBuyOrderNumStatVos = groupBuyOrderService.statisticsGroupOrderNumByActiveIds(Collections.singletonList(activeId));
            if (!CollectionUtils.isEmpty(groupBuyOrderNumStatVos)) {
                Integer successfulGroupOrderNum = groupBuyOrderNumStatVos.get(0).getSuccessfulGroupOrderNum();
                activeOrderStatisticsVo.setSuccessfulGroupOrderNum(successfulGroupOrderNum);
            }
        }
    }


    @Override
    public CreateOrderVo createOrder(CreateOrderDto createOrderDto) {
        Integer orderNum = createOrderDto.getOrderNum();
        Long activeId = createOrderDto.getActiveId();
        if (activeId == null || activeId <= 0) {
            Throw.isBusinessException("请选择下单的活动");
        }

        if (orderNum == null || orderNum <= 0) {
            Throw.isBusinessException("请选择下单数量");
        }

        AppUserVo appUserVo = appUserApi.getById(createOrderDto.getUserId()).unpack();
        if (appUserVo == null || StringUtils.isBlank(appUserVo.getOpenid())) {
            Throw.isBusinessException("请先授权");
        }

        // 对活动id加锁
        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "createOrder:" + activeId);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            // 判断活动时间
            ActiveVo activeVo = activeApi.getById(activeId).unpack();
            if (activeVo == null || activeVo.getDelState() != 0 || ActiveStateEnum.NO_RELEASE.getValue().equals(activeVo.getActiveState())) {
                Throw.isBusinessException(ResponseEnums.ACTIVE_DOWN);
            }

            List<Integer> supportActiveTypes = Arrays.asList(
                    ActiveTypeEnum.GROUP.getValue(), ActiveTypeEnum.ENROLL.getValue(), ActiveTypeEnum.GROUP_ENROLL.getValue());
            Integer activeType = activeVo.getActiveType();
            if (!supportActiveTypes.contains(activeType)) {
                Throw.isBusinessException("该活动不支持下单");
            }

            CreateOrderVo order = OrderFactory.getOrderHandler(activeType).createOrder(createOrderDto, activeVo);
            if (order != null && !StringUtils.isBlank(order.getOrderNo()) && ZeroStateEnum.NO.getValue().equals(order.getZeroState())) {
                // 发送延时订单消息
                orderDelayMsgProvider.sendMsg(order.getOrderNo());
            }

            return order;
        } finally {
            LockUtils.unlock(lockKey);
        }
    }

    @Override
    public CreateOrderVo createGroupBuyOrder(CreateOrderDto createOrderDto) {
        AppUserVo appUserVo = appUserApi.getById(createOrderDto.getUserId()).unpack();
        if (appUserVo == null || StringUtils.isBlank(appUserVo.getOpenid())) {
            Throw.isBusinessException("请先授权");
        }
        OrderContext orderContext = new OrderContext();
        createOrderDto.setPromotionType(PromotionTypeEnum.GROUP_BUY);
        orderContext.setCreateOrderDto(createOrderDto);
        return orderBuilder.createGroupBuyOrder(orderContext);
    }

    @Override
    public CreateOrderVo createPointsOrder(CreateOrderDto createOrderDto) {
        Long productId = createOrderDto.getPointsProductId();
        if (productId == null || productId <= 0) {
            Throw.isBusinessException("兑换商品id有误");
        }

        AppUserVo appUserVo = appUserApi.getById(createOrderDto.getUserId()).unpack();
        if (appUserVo == null || StringUtils.isBlank(appUserVo.getOpenid())) {
            Throw.isBusinessException("请先授权");
        }
        Long userId = appUserVo.getId();

        // 对商品id加锁
        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "createPointsOrder:" + productId + ":user:" + userId);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            BusinessPointsMallProductVo productVo = businessPointsMallApi.productDetail(productId, userId).unpack();
            if (productVo == null || productVo.getDelState() != 0) {
                Throw.isBusinessException("积分商品已下架");
            }

            if (!productVo.getProductType().equals(BusinessPointsMallProductTypeEnum.GOODS.getValue())) {
                Throw.isBusinessException("积分商品类型有误");
            }

            LocalDateTime now = LocalDateTime.now();
            if (productVo.getEffectiveTime().isAfter(now)) {
                Throw.isBusinessException("该积分商品还未到生效时间");
            }

            if (productVo.getRemainNum() <= 0) {
                Throw.isBusinessException("该商品已兑完");
            }

            return OrderFactory.getOrderHandler(ActiveTypeEnum.POINTS.getValue()).createPointsOrder(createOrderDto, productVo);
        } finally {
            LockUtils.unlock(lockKey);
        }
    }

    @Override
    public OrderPayVo pay(OrderPayDto orderPayDto) {
        String orderNo = orderPayDto.getOrderNo();
        if (StringUtils.isBlank(orderNo)) {
            Throw.isBusinessException("未找到订单数据");
        }

        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "payOrder:" + orderNo);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                    .eq("order_no", orderNo).eq("user_id", orderPayDto.getUserId()));
            if (CollectionUtils.isEmpty(tbOrderPos)) {
                Throw.isBusinessException("未找到订单数据");
            }

            TbOrderPo tbOrderPo = tbOrderPos.get(0);
            if (!OrderStateEnum.WAIT_PAY.getValue().equals(tbOrderPo.getOrderState())) {
                Throw.isBusinessException(ResponseEnums.ORDER_HANDLE);
            }

            Integer zeroState = tbOrderPo.getZeroState();
            if (ZeroStateEnum.YES.getValue().equals(zeroState)) {
                OrderPayVo orderPayVo = new OrderPayVo();
                orderPayVo.setOrderNo(tbOrderPo.getOrderNo());

                return orderPayVo;
            }

            // 判断活动是否已结束
            if (tbOrderPo.getEndTime().compareTo(LocalDateTime.now()) <= 0) {
                // 更新订单状态，待支付--》已关闭
                OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                orderStateUpdateParam.setId(tbOrderPo.getId());
                orderStateUpdateParam.setOrgOrderState(OrderStateEnum.WAIT_PAY.getValue());
                orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                // 订单备注=超时未支付,系统自动关闭
                orderStateUpdateParam.setOrderNote(OrderNoteConstant.THREE);
                orderStateUpdateParam.setCloseTime(LocalDateTime.now());
                baseMapper.updateOrderState(orderStateUpdateParam);

                Throw.isBusinessException(ResponseEnums.ORDER_ACTIVE_END);
            }

            // 判断订单是否超时
            if (tbOrderPo.getOrderTime().plusMinutes(Constant.ORDER_DELAY_TIME).compareTo(LocalDateTime.now()) <= 0) {
                // 更新订单状态，待支付--》已关闭
                OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                orderStateUpdateParam.setId(tbOrderPo.getId());
                orderStateUpdateParam.setOrgOrderState(OrderStateEnum.WAIT_PAY.getValue());
                orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                // 订单备注=超时未支付,系统自动关闭
                orderStateUpdateParam.setOrderNote(OrderNoteConstant.THREE);
                orderStateUpdateParam.setCloseTime(LocalDateTime.now());
                baseMapper.updateOrderState(orderStateUpdateParam);

                Throw.isBusinessException(ResponseEnums.ORDER_TIME_OUT);
            }

            String hfReqDate = tbOrderPo.getHfReqDate();
            String hfReqSeqId = tbOrderPo.getHfReqSeqId();

            if (!StringUtils.isBlank(hfReqDate) && !StringUtils.isBlank(hfReqSeqId)) {
                // 再次调用查单，如果成功/失败，则返回订单已支付，请刷新
                HfTradeQuery hfTradeQuery = new HfTradeQuery();
                hfTradeQuery.setOrgReqDate(hfReqDate);
                hfTradeQuery.setOrgReqSeqId(hfReqSeqId);
                JSONObject jsonObject = hfApi.tradeQuery(hfTradeQuery).unpack();
                if (jsonObject != null) {
                    JSONObject dataJSONObject = jsonObject.getJSONObject("data");
                    // 交易状态	P：处理中；S：成功；F：失败；I: 初始（初始状态很罕见，请联系汇付技术人员处理）；
                    String transStat = dataJSONObject.getString("trans_stat");
                    // NOTPAY，订单未支付
                    String bankCode = dataJSONObject.getString("bank_code");
                    log.info("立即支付，查单成功，订单第三方交易状态：【{}】，orderNo：{}，bankCode：{}", transStat, tbOrderPo.getOrderNo(), bankCode);
                    if ("S".equals(transStat)) {
                        PaySuccessOrderParam paySuccessOrderParam = new PaySuccessOrderParam();
                        paySuccessOrderParam.setId(tbOrderPo.getId());
                        paySuccessOrderParam.setOrgOrderState(OrderStateEnum.WAIT_PAY.getValue());
                        paySuccessOrderParam.setBusinessId(tbOrderPo.getBusinessId());
                        paySuccessOrderParam.setUserId(tbOrderPo.getUserId());
                        paySuccessOrderParam.setOrderTime(tbOrderPo.getOrderTime());
                        paySuccess(paySuccessOrderParam);

                        Throw.isBusinessException(ResponseEnums.ORDER_PAYED);
                    }

                    if ("F".equals(transStat)) {
                        // 如果活动已结束或订单超时，则关闭订单
                        if (tbOrderPo.getEndTime().compareTo(LocalDateTime.now()) <= 0
                                || tbOrderPo.getOrderTime().plusMinutes(Constant.ORDER_DELAY_TIME).compareTo(LocalDateTime.now()) <= 0) {
                            // 查单是支付失败，将待支付--》已关闭
                            OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                            orderStateUpdateParam.setId(tbOrderPo.getId());
                            orderStateUpdateParam.setOrgOrderState(OrderStateEnum.WAIT_PAY.getValue());
                            orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                            // 订单备注=超时未支付,系统自动关闭
                            orderStateUpdateParam.setOrderNote(OrderNoteConstant.THREE);
                            orderStateUpdateParam.setCloseTime(LocalDateTime.now());

                            orderStateUpdateParam.setUpdateTime(LocalDateTime.now());
                            baseMapper.updateOrderState(orderStateUpdateParam);

                            Throw.isBusinessException(ResponseEnums.ORDER_TIME_OUT);
                        }
                    }
                }
            }

            Long userId = tbOrderPo.getUserId();
            AppUserVo appUserVo = appUserApi.getById(userId).unpack();

            LocalDateTime nowLocalDateTime = LocalDateUtil.getNowLocalDateTime();
            String yyyyMMdd = LocalDateUtil.toLocalDateToString(nowLocalDateTime.toLocalDate(), "yyyyMMdd");
            String reqSeqId = LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime, "yyyyMMddHHmmss") + GenerateUtil.getRandomNum(5);
            String timeExpire = LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime.plusMinutes(30), "yyyyMMddHHmmss");

            HfJsPay hfJsPay = new HfJsPay();
            hfJsPay.setWxOpenid(appUserVo.getOpenid());
            hfJsPay.setReqSeqId(reqSeqId);
            hfJsPay.setReqDate(yyyyMMdd);
            hfJsPay.setTimeExpire(timeExpire);
            hfJsPay.setTransAmt(tbOrderPo.getPayPrice().setScale(2, BigDecimal.ROUND_DOWN).toString());
            hfJsPay.setGoodsDesc(tbOrderPo.getActiveTitle());
            hfJsPay.setAttach(PayAttachEnum.ORDER_PAY.getName());
            JSONObject jsonObject = hfApi.jsPay(hfJsPay).unpack();
            if (jsonObject == null) {
                log.error("下单失败，调用hf支付接口错误，hf返回数据为空");
                Throw.isBusinessException("下单失败");
            }

            JSONObject dataJSONObject = jsonObject.getJSONObject("data");
            String respCode = dataJSONObject.getString("resp_code");
            if (!"00000000".equals(respCode) && !"00000100".equals(respCode)) {
                log.error("下单失败，调用hf支付接口错误，data:{}", JSON.toJSONString(dataJSONObject));
                Throw.isBusinessException("下单失败");
            }

            String payInfo = dataJSONObject.getString("pay_info");
//            String preOrderId = dataJSONObject.getString("pre_order_id");
            String partyOrderId = dataJSONObject.getString("party_order_id");
            if (StringUtils.isBlank(payInfo) || StringUtils.isBlank(partyOrderId)) {
                log.error("下单失败，调用hf支付接口返回数据有误，data:{}", JSON.toJSONString(dataJSONObject));
                Throw.isBusinessException("下单失败");
            }

            if (!payHandler(tbOrderPo, nowLocalDateTime, yyyyMMdd, reqSeqId, partyOrderId)) {
                Throw.isBusinessException("订单已处理，请刷新~");
            }

            OrderPayVo orderPayVo = new OrderPayVo();
            orderPayVo.setOrderNo(payInfo);

            return orderPayVo;
        } finally {
            LockUtils.unlock(lockKey);
        }
    }

    private Boolean payHandler(TbOrderPo tbOrderPo, LocalDateTime nowLocalDateTime, String yyyyMMdd, String reqSeqId, String partyOrderId) {
        TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

        try {
            OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
            orderStateUpdateParam.setId(tbOrderPo.getId());
            orderStateUpdateParam.setPreOrderId(partyOrderId);
            orderStateUpdateParam.setHfReqSeqId(reqSeqId);
            orderStateUpdateParam.setHfReqDate(yyyyMMdd);
            // 更新订单状态，待支付--》支付中
            orderStateUpdateParam.setOrgOrderState(OrderStateEnum.WAIT_PAY.getValue());
            orderStateUpdateParam.setOrderState(OrderStateEnum.PAYING.getValue());
            int update = baseMapper.updateOrderState(orderStateUpdateParam);
            if (update == 0) {
                log.error("立即支付失败，更新订单状态失败，orderId：{}", tbOrderPo.getId());
                Throw.isBusinessException("订单已处理，请刷新~");
            }

            TbOrderPayRecordPo tbOrderPayRecordPo = new TbOrderPayRecordPo();
            tbOrderPayRecordPo.setOrderId(tbOrderPo.getId());
            tbOrderPayRecordPo.setReqDate(yyyyMMdd);
            tbOrderPayRecordPo.setReqSeqId(reqSeqId);
            tbOrderPayRecordPo.setTradeAmt(tbOrderPo.getPayPrice());
            tbOrderPayRecordPo.setTradeState(OrderPayRecordTradeStateEnum.NO_PAY.getValue());
            tbOrderPayRecordPo.setCreateTime(nowLocalDateTime);
            tbOrderPayRecordPo.setUpdateTime(nowLocalDateTime);
            int insert = orderPayRecordMapper.insert(tbOrderPayRecordPo);
            if (insert == 0) {
                log.error("立即支付失败，保存订单支付记录失败，orderId：{}", tbOrderPo.getId());
                Throw.isBusinessException("订单已处理，请刷新~");
            }

            transactionManager.commit(transaction);
        } catch (Exception e) {
            //回滚事务
            transactionManager.rollback(transaction);
            log.error("<立即支付>事务异常回滚", e);
            return false;
        }

        return true;
    }

    @Override
    public Boolean preOrderCallback(JSONObject dataObj) {
        String subRespCode = dataObj.getString("sub_resp_code");
        String subRespDesc = dataObj.getString("sub_resp_desc");
        String hfMerchantNo = dataObj.getString("huifu_id");
        String reqDate = dataObj.getString("req_date");
        String reqSeqId = dataObj.getString("req_seq_id");
        // 交易状态	S：成功、F：失败；
        String transStat = dataObj.getString("trans_stat");

        List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                .eq("hf_req_seq_id", reqSeqId).eq("hf_req_date", reqDate));
        if (!CollectionUtils.isEmpty(tbOrderPos)) {
            TbOrderPo tbOrderPo = tbOrderPos.get(0);

            if (!OrderStateEnum.PAYING.getValue().equals(tbOrderPo.getOrderState())) {
                log.error("预订单回调处理，订单非支付中状态，orderId:{}", tbOrderPo.getId());
                return false;
            }

            // 添加汇付申请单记录（微信小程序预下单支付回调，异步回调接口）
            HfRequestRecordSaveDto hfRequestRecordSaveDto = new HfRequestRecordSaveDto();
            hfRequestRecordSaveDto.setApplyType(HfRequestRecordApplyTypeEnum.WX_PRE_ORDER_ASYNC.getValue());
            hfRequestRecordSaveDto.setRequestType(HfRequestRecordRequestTypeEnum.ASYNC.getValue());
            hfRequestRecordSaveDto.setApplyNo("");
            hfRequestRecordSaveDto.setHuifuId(hfMerchantNo);
            hfRequestRecordSaveDto.setHfApplyNo(tbOrderPo.getPreOrderId());
            hfRequestRecordSaveDto.setDataResult(JSON.toJSONString(dataObj));
            hfRequestRecordSaveDto.setReqSeqId(reqSeqId);
            hfRequestRecordSaveDto.setRespCode(subRespCode);
            hfRequestRecordSaveDto.setRespDesc(subRespDesc);
            hfRequestRecordSaveDto.setCreateTime(LocalDateTime.now());
            hfRequestRecordSaveDto.setUpdateTime(LocalDateTime.now());
            Boolean saveRequestRecordState = hfRequestRecordApi.saveRequestRecord(hfRequestRecordSaveDto).unpack();
            if (!saveRequestRecordState) {
                log.error("添加汇付申请单记录失败（微信小程序预下单支付回调，异步回调接口），hfRequestRecordSaveDto：{}", JSON.toJSONString(hfRequestRecordSaveDto));
            }

            if ("S".equals(transStat)) {
                // 如果交易成功，修改订单状态
                PaySuccessOrderParam paySuccessOrderParam = new PaySuccessOrderParam();
                paySuccessOrderParam.setId(tbOrderPo.getId());
                paySuccessOrderParam.setBusinessId(tbOrderPo.getBusinessId());
                paySuccessOrderParam.setUserId(tbOrderPo.getUserId());
                paySuccessOrderParam.setOrderTime(tbOrderPo.getOrderTime());
                paySuccess(paySuccessOrderParam);
            }
        }

        return true;
    }

    private void paySuccess(PaySuccessOrderParam paySuccessOrderParam) {
        Long agentId = 0L;
        String orderNo = "";
        BigDecimal actualCommissionAmt = BigDecimal.ZERO;
        Long id = paySuccessOrderParam.getId();
        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "orderPaySuccess:" + id);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            TbOrderPo orderPo = baseMapper.selectById(id);
            if (!OrderStateEnum.PAYING.getValue().equals(orderPo.getOrderState()) && !OrderStateEnum.WAIT_PAY.getValue().equals(orderPo.getOrderState())) {
                log.error("订单支付成功处理，订单非支付中/待支付状态，orderId:{}", paySuccessOrderParam.getId());
                return;
            }
            agentId = orderPo.getAgentId();
            orderNo = orderPo.getOrderNo();
            // 实际全核销佣金金额
            actualCommissionAmt = orderPo.getActualCommissionAmt();

            OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
            orderStateUpdateParam.setId(id);
            orderStateUpdateParam.setOrgOrderState(paySuccessOrderParam.getOrgOrderState());
            ActiveVo activeVo = activeApi.getById(orderPo.getActiveId()).unpack();
            // 如果活动需要审核，则状态为待审核状态，需要在商家后台审核
            if (activeVo.getAuditRequired() != null && activeVo.getAuditRequired() == 1) {
                orderStateUpdateParam.setOrderState(OrderStateEnum.WAIT_AUDIT.getValue());
                orderStateUpdateParam.setOrderNote(OrderNoteConstant.EIGHT);
            } else {
                orderStateUpdateParam.setOrderState(OrderStateEnum.WAIT_VERIFY.getValue());
            }
            // 如果是拼团订单支付成功，状态更新为待成团
            if (PromotionTypeEnum.GROUP_BUY.name().equals(orderPo.getPromotionType())) {
                orderStateUpdateParam.setOrderState(OrderStateEnum.WAIT_GROUP.getValue());
            }

            orderStateUpdateParam.setPayTime(LocalDateTime.now());

            TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

            try {
                // 更新订单状态，由支付中/待支付-》待核销
                Integer update = baseMapper.updateOrderState(orderStateUpdateParam);
                if (update == 0) {
                    log.error("订单支付成功处理，更新订单状态失败，orderId:{}", paySuccessOrderParam.getId());
                    Throw.isBusinessException("支付失败");
                }

                // 如果活动需要审核，则状态为待审核状态，需要在商家后台审核
                Integer subOrderState = SubOrderStateEnum.WAIT_VERIFY.getValue();
                if (activeVo.getAuditRequired() != null && activeVo.getAuditRequired() == 1) {
                    subOrderState = SubOrderStateEnum.WAIT_AUDIT.getValue();
                }
                update = orderItemMapper.updateSubOrderStateByOrderId(paySuccessOrderParam.getId(), subOrderState);
                if (update == 0) {
                    log.error("订单支付成功处理，更新子订单状态失败，orderId:{}", paySuccessOrderParam.getId());
                    Throw.isBusinessException("支付失败");
                }

                // 判断下单用户是否是商家的首次下单，如果是则记录
                Integer count = orderFirstRecordMapper.selectCount(new QueryWrapper<TbOrderFirstRecordPo>().eq("del_state", 0)
                        .eq("user_id", paySuccessOrderParam.getUserId()).eq("business_id", paySuccessOrderParam.getBusinessId()));
                if (count == null || count <= 0) {
                    TbOrderFirstRecordPo tbOrderFirstRecordPo = new TbOrderFirstRecordPo();
                    tbOrderFirstRecordPo.setBusinessId(paySuccessOrderParam.getBusinessId());
                    tbOrderFirstRecordPo.setOrderId(paySuccessOrderParam.getId());
                    tbOrderFirstRecordPo.setUserId(paySuccessOrderParam.getUserId());
                    tbOrderFirstRecordPo.setOrderTime(paySuccessOrderParam.getOrderTime());
                    tbOrderFirstRecordPo.setCreateTime(LocalDateTime.now());
                    tbOrderFirstRecordPo.setUpdateTime(LocalDateTime.now());
                    orderFirstRecordMapper.insert(tbOrderFirstRecordPo);
                }

                AppUserVo appUserVo = appUserApi.getById(orderPo.getUserId()).unpack();
                List<TbOrderItemPo> tbOrderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                        .eq("order_id", paySuccessOrderParam.getId()));
                Long refundId = null;
                for (TbOrderItemPo tbOrderItemPo : tbOrderItemPos) {
                    if (!VerifyTypeEnum.TYF.getValue().equals(tbOrderItemPo.getVerifyType())) {
                        continue;
                    }
                    PftOrderSubmitResult orderSubmitResult = pftService.orderSubmit(tbOrderItemPo, appUserVo);
                    if (StringUtils.isBlank(orderSubmitResult.getUuordernum())) {
                        log.error("【" + orderPo.getOrderNo() + "】订单项【" + tbOrderItemPo.getSubOrderNo() + "】票付通订单生成失败" + JSONObject.toJSONString(orderSubmitResult));
                        refundId = this.cancelOrderPft(id);
                        break;
                    }
                    if (StringUtils.isBlank(orderSubmitResult.getUucode())) {
                        // 凭证生成失败，异步出票会赋值
                        log.error("【" + orderPo.getOrderNo() + "】订单项【" + tbOrderItemPo.getSubOrderNo() + "】票付通订单凭证码生成失败" + JSONObject.toJSONString(orderSubmitResult));
                    }
                    orderItemMapper.updatePftResult(tbOrderItemPo.getId(), orderSubmitResult.getUuordernum(), orderSubmitResult.getUucode());
                }

                transactionManager.commit(transaction);
                if (refundId != null) {
                    orderRefundMsgProvider.sendMsg(refundId);
                }
            } catch (Exception e) {
                //回滚事务
                transactionManager.rollback(transaction);
                log.error("<活动订单支付成功处理>事务异常回滚", e);
                return;
            }
            // 拼团订单
            if (orderPo.getPromotionType() != null && PromotionTypeEnum.GROUP_BUY.name().equals(orderPo.getPromotionType())) {
                groupBuyOrderService.updateGroupAfterPayment(orderPo.getId());
            }
        } finally {
            LockUtils.unlock(lockKey);
        }


        // 如果是分佣订单,发送新推广订单的系统通知
        if (agentId != null && agentId > 0 && !StringUtils.isBlank(orderNo)) {
            if (actualCommissionAmt.compareTo(BigDecimal.ZERO) > 0) {
                // 发送新推广订单系统通知
                NotifyMsgSendDto notifyMsgSendDto = new NotifyMsgSendDto();
                notifyMsgSendDto.setUserId(agentId);
                notifyMsgSendDto.setRoleType(RoleTypeEnum.BUSINESS.getValue());
                notifyMsgSendDto.setMsgType(NotifyMsgTypeEnum.AGENT_NEW_ORDER.getValue());
                notifyMsgSendDto.setContent(String.format(MsgConstant.AGENT_NEW_ORDER_COMMISSION, orderNo, actualCommissionAmt.toString()));
                notifyMsgSendDto.setMsgState(NotifyMsgStateEnum.NO_READ.getValue());
                notifyMsgProvider.sendMsg(notifyMsgSendDto);
            } else {
                // 发送新推广订单系统通知
                NotifyMsgSendDto notifyMsgSendDto = new NotifyMsgSendDto();
                notifyMsgSendDto.setUserId(agentId);
                notifyMsgSendDto.setRoleType(RoleTypeEnum.BUSINESS.getValue());
                notifyMsgSendDto.setMsgType(NotifyMsgTypeEnum.AGENT_NEW_ORDER.getValue());
                notifyMsgSendDto.setContent(String.format(MsgConstant.AGENT_NEW_ORDER, orderNo));
                notifyMsgSendDto.setMsgState(NotifyMsgStateEnum.NO_READ.getValue());
                notifyMsgProvider.sendMsg(notifyMsgSendDto);
            }

        }
    }

    @Override
    public Boolean jsPayCallback(JSONObject dataObj) {
        String subRespCode = dataObj.getString("sub_resp_code");
        String subRespDesc = dataObj.getString("sub_resp_desc");
        String hfMerchantNo = dataObj.getString("huifu_id");
        String reqDate = dataObj.getString("req_date");
        String reqSeqId = dataObj.getString("req_seq_id");
        // 交易状态	S：成功、F：失败；
        String transStat = dataObj.getString("trans_stat");

        // 添加汇付申请单记录（聚合支付下单回调，异步回调接口）
        HfRequestRecordSaveDto hfRequestRecordSaveDto = new HfRequestRecordSaveDto();
        hfRequestRecordSaveDto.setApplyType(HfRequestRecordApplyTypeEnum.WX_JS_ORDER_ASYNC.getValue());
        hfRequestRecordSaveDto.setRequestType(HfRequestRecordRequestTypeEnum.ASYNC.getValue());
        hfRequestRecordSaveDto.setApplyNo(PayAttachEnum.ORDER_PAY.getName());
        hfRequestRecordSaveDto.setHuifuId(hfMerchantNo);
        hfRequestRecordSaveDto.setHfApplyNo(reqDate);
        hfRequestRecordSaveDto.setDataResult(JSON.toJSONString(dataObj));
        hfRequestRecordSaveDto.setReqSeqId(reqSeqId);
        hfRequestRecordSaveDto.setRespCode(subRespCode);
        hfRequestRecordSaveDto.setRespDesc(subRespDesc);
        hfRequestRecordSaveDto.setCreateTime(LocalDateTime.now());
        hfRequestRecordSaveDto.setUpdateTime(LocalDateTime.now());
        Boolean saveRequestRecordState = hfRequestRecordApi.saveRequestRecord(hfRequestRecordSaveDto).unpack();
        if (!saveRequestRecordState) {
            log.error("添加汇付申请单记录失败（聚合支付下单回调-用户下单，异步回调接口），hfRequestRecordSaveDto：{}", JSON.toJSONString(hfRequestRecordSaveDto));
        }

        if ("00000000".equals(subRespCode) && "S".equals(transStat)) {
            Long orderId = null;
            List<TbOrderPayRecordPo> tbOrderPayRecordPos = orderPayRecordMapper.selectList(new QueryWrapper<TbOrderPayRecordPo>().eq("del_state", 0)
                    .eq("req_seq_id", reqSeqId).eq("req_date", reqDate));
            if (!CollectionUtils.isEmpty(tbOrderPayRecordPos)) {
                TbOrderPayRecordPo tbOrderPayRecordPo = tbOrderPayRecordPos.get(0);

                // 更新订单支付记录为支付成功，待支付-》支付成功
                orderPayRecordMapper.updateTradeState(tbOrderPayRecordPo.getId(),
                        OrderPayRecordTradeStateEnum.NO_PAY.getValue(),
                        OrderPayRecordTradeStateEnum.PAY_SUCCESS.getValue(),
                        LocalDateTime.now(),
                        "");
                orderId = tbOrderPayRecordPo.getOrderId();
            }

            TbOrderPo tbOrderPo;
            List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                    .eq("hf_req_seq_id", reqSeqId).eq("hf_req_date", reqDate));
            if (!CollectionUtils.isEmpty(tbOrderPos)) {
                tbOrderPo = tbOrderPos.get(0);
            } else {
                tbOrderPo = baseMapper.selectById(orderId);
            }

            if (tbOrderPo != null) {
                if (!OrderStateEnum.PAYING.getValue().equals(tbOrderPo.getOrderState()) && !OrderStateEnum.WAIT_PAY.getValue().equals(tbOrderPo.getOrderState())) {
                    log.error("jsPay回调失败，用户下单订单非待支付/支付中状态，orderId:{}", tbOrderPo.getId());

                    // 根据订单id查询订单支付记录，判断是否存在多条支付成功记录，如果存在，则更新记录并退款
                    checkOrderPayRecord(tbOrderPo);

                    return false;
                }

                // 如果交易成功，修改订单状态
                PaySuccessOrderParam paySuccessOrderParam = new PaySuccessOrderParam();
                paySuccessOrderParam.setId(tbOrderPo.getId());
                paySuccessOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
                paySuccessOrderParam.setBusinessId(tbOrderPo.getBusinessId());
                paySuccessOrderParam.setUserId(tbOrderPo.getUserId());
                paySuccessOrderParam.setOrderTime(tbOrderPo.getOrderTime());
                paySuccess(paySuccessOrderParam);

                // 根据订单id查询订单支付记录，判断是否存在多条支付成功记录，如果存在，则更新记录并退款
                checkOrderPayRecord(tbOrderPo);

                return true;
            }
        }

        if ("F".equals(transStat)) {
            // 更新订单支付记录为支付失败。待支付-》支付失败
            List<TbOrderPayRecordPo> tbOrderPayRecordPos = orderPayRecordMapper.selectList(new QueryWrapper<TbOrderPayRecordPo>().eq("del_state", 0)
                    .eq("req_seq_id", reqSeqId).eq("req_date", reqDate)
                    .eq("trade_state", OrderPayRecordTradeStateEnum.NO_PAY.getValue()));
            if (!CollectionUtils.isEmpty(tbOrderPayRecordPos)) {
                String bankMessage = dataObj.getString("bank_message");

                orderPayRecordMapper.updateTradeState(tbOrderPayRecordPos.get(0).getId(),
                        OrderPayRecordTradeStateEnum.NO_PAY.getValue(),
                        OrderPayRecordTradeStateEnum.PAY_FAIL.getValue(),
                        LocalDateTime.now(),
                        bankMessage);
            }
        }

        return true;
    }

    private void checkOrderPayRecord(TbOrderPo tbOrderPo) {
        List<TbOrderPayRecordPo> tbOrderPayRecordPoList = orderPayRecordMapper.selectList(new QueryWrapper<TbOrderPayRecordPo>().eq("del_state", 0)
                .eq("order_id", tbOrderPo.getId()).eq("trade_state", OrderPayRecordTradeStateEnum.PAY_SUCCESS.getValue())
                .orderByAsc("update_time"));
        if (!CollectionUtils.isEmpty(tbOrderPayRecordPoList)) {
            TbOrderPayRecordPo tbOrderPayRecordPo = tbOrderPayRecordPoList.get(0);
            Long getId = tbOrderPayRecordPo.getId();
            String getReqSeqId = tbOrderPayRecordPo.getReqSeqId();
            String getReqDate = tbOrderPayRecordPo.getReqDate();

            // 更新订单的hf请求日期和请求流水号
            if (!tbOrderPo.getHfReqSeqId().equals(getReqSeqId) || !tbOrderPo.getHfReqDate().equals(getReqDate)) {
                if (OrderStateEnum.WAIT_PAY.getValue().equals(tbOrderPo.getOrderState()) || OrderStateEnum.PAYING.getValue().equals(tbOrderPo.getOrderState())) {
                    baseMapper.updateHfReqData(tbOrderPo.getId(), getReqSeqId, getReqDate);
                }
            }

            if (tbOrderPayRecordPoList.size() > 1) {
                for (TbOrderPayRecordPo orderPayRecordPo : tbOrderPayRecordPoList) {
                    Long id = orderPayRecordPo.getId();
                    if (getId.equals(id)) {
                        continue;
                    }

                    orderPayRecordPo.setTradeState(OrderPayRecordTradeStateEnum.REFUNDING.getValue());
                    orderPayRecordPo.setUpdateTime(LocalDateTime.now());
                    orderPayRecordPo.setRefundAmt(orderPayRecordPo.getTradeAmt());

                    // 调用hf退款接口申请退款
                    HfTradeRefund hfTradeRefund = new HfTradeRefund();
                    hfTradeRefund.setOrgReqDate(orderPayRecordPo.getReqDate());
                    hfTradeRefund.setOrgReqSeqId(orderPayRecordPo.getReqSeqId());
                    hfTradeRefund.setReqDate(orderPayRecordPo.getRefundReqDate());
                    hfTradeRefund.setReqSeqId(orderPayRecordPo.getRefundReqSeqId());
                    hfTradeRefund.setRefundAmt(orderPayRecordPo.getRefundAmt());
                    JSONObject jsonObject = hfApi.tradeRefund(hfTradeRefund).unpack();
                    if (jsonObject == null) {
                        log.error("订单退款失败，调用hf退款接口失败，orderPayRecordId：{}", orderPayRecordPo.getId());
                        continue;
                    }

                    JSONObject dataJSONObject = jsonObject.getJSONObject("data");
                    // 交易状态	P：处理中、S：成功、F：失败；
                    String refundTransStat = dataJSONObject.getString("trans_stat");
                    if ("P".equals(refundTransStat)) {
                        orderPayRecordPo.setTradeState(OrderPayRecordTradeStateEnum.REFUNDING.getValue());
                    } else if ("S".equals(refundTransStat)) {
                        orderPayRecordPo.setTradeState(OrderRefundStateEnum.SUCCESS.getValue());
                    } else if ("F".equals(refundTransStat)) {
                        orderPayRecordPo.setTradeState(OrderRefundStateEnum.FAIL.getValue());
                        orderPayRecordPo.setRefundFailReason(JSON.toJSONString(dataJSONObject));
                    }

                    orderPayRecordMapper.updateById(orderPayRecordPo);
                }
            }
        }
    }

    @Override
    public Boolean refundCallback(JSONObject dataObj) {
        String subRespCode = dataObj.getString("sub_resp_code");
        String subRespDesc = dataObj.getString("sub_resp_desc");
        String hfMerchantNo = dataObj.getString("huifu_id");
        String reqDate = dataObj.getString("req_date");
        String reqSeqId = dataObj.getString("req_seq_id");
        String orgReqDate = dataObj.getString("org_req_date");
        String orgReqSeqId = dataObj.getString("org_req_seq_id");
        // 交易状态	P：处理中、S：成功、F：失败；
        String transStat = dataObj.getString("trans_stat");
        String ordAmt = dataObj.getString("ord_amt");

        // 添加汇付申请单记录（交易退款回调，异步回调接口）
        HfRequestRecordSaveDto hfRequestRecordSaveDto = new HfRequestRecordSaveDto();
        hfRequestRecordSaveDto.setApplyType(HfRequestRecordApplyTypeEnum.TRADE_REFUND_ASYNC.getValue());
        hfRequestRecordSaveDto.setRequestType(HfRequestRecordRequestTypeEnum.ASYNC.getValue());
        hfRequestRecordSaveDto.setApplyNo("");
        hfRequestRecordSaveDto.setHuifuId(hfMerchantNo);
        hfRequestRecordSaveDto.setHfApplyNo("");
        hfRequestRecordSaveDto.setDataResult(JSON.toJSONString(dataObj));
        hfRequestRecordSaveDto.setReqSeqId(reqSeqId);
        hfRequestRecordSaveDto.setRespCode(subRespCode);
        hfRequestRecordSaveDto.setRespDesc(subRespDesc);
        hfRequestRecordSaveDto.setCreateTime(LocalDateTime.now());
        hfRequestRecordSaveDto.setUpdateTime(LocalDateTime.now());
        Boolean saveRequestRecordState = hfRequestRecordApi.saveRequestRecord(hfRequestRecordSaveDto).unpack();
        if (!saveRequestRecordState) {
            log.error("添加汇付申请单记录失败（交易退款回调，异步回调接口），hfRequestRecordSaveDto：{}", JSON.toJSONString(hfRequestRecordSaveDto));
        }

        List<TbOrderRefundPo> tbOrderRefundPos = orderRefundMapper.selectList(new QueryWrapper<TbOrderRefundPo>().eq("del_state", 0)
                .eq("org_req_date", orgReqDate).eq("org_req_seq_id", orgReqSeqId));
        if (!CollectionUtils.isEmpty(tbOrderRefundPos)) {
            TbOrderRefundPo tbOrderRefundPo = tbOrderRefundPos.get(0);
            if (!OrderRefundStateEnum.WAIT.getValue().equals(tbOrderRefundPo.getRefundState())
                    && !OrderRefundStateEnum.PROCESSING.getValue().equals(tbOrderRefundPo.getRefundState())) {
                log.error("订单退款回调失败，订单退款记录已处理：reqDate：{}， reqSeqId：{}", reqDate, reqSeqId);
                return false;
            }

            if ("P".equals(transStat)) {
                tbOrderRefundPo.setRefundState(OrderRefundStateEnum.PROCESSING.getValue());
            } else if ("S".equals(transStat)) {
                tbOrderRefundPo.setRefundState(OrderRefundStateEnum.SUCCESS.getValue());
                tbOrderRefundPo.setRefundFinishTime(LocalDateTime.now());
            } else if ("F".equals(transStat)) {
                tbOrderRefundPo.setRefundState(OrderRefundStateEnum.FAIL.getValue());
                tbOrderRefundPo.setRefundReason(JSON.toJSONString(dataObj));
            }

            tbOrderRefundPo.setReqDate(reqDate);
            tbOrderRefundPo.setReqSeqId(reqSeqId);
            tbOrderRefundPo.setUpdateTime(LocalDateTime.now());
            orderRefundMapper.updateById(tbOrderRefundPo);
        }

        List<TbOrderPayRecordPo> tbOrderPayRecordPos = orderPayRecordMapper.selectList(new QueryWrapper<TbOrderPayRecordPo>().eq("del_state", 0)
                .eq("req_date", orgReqDate).eq("req_seq_id", orgReqSeqId));
        if (!CollectionUtils.isEmpty(tbOrderPayRecordPos)) {
            TbOrderPayRecordPo tbOrderPayRecordPo = tbOrderPayRecordPos.get(0);
//            if (!OrderPayRecordTradeStateEnum.REFUNDING.getValue().equals(tbOrderPayRecordPo.getTradeState())) {
//                log.error("订单退款回调失败，订单支付记录退款记录已处理：reqDate：{}， reqSeqId：{}", reqDate, reqSeqId);
//                return false;
//            }

            if ("P".equals(transStat)) {
                tbOrderPayRecordPo.setTradeState(OrderPayRecordTradeStateEnum.REFUNDING.getValue());
            } else if ("S".equals(transStat)) {
                tbOrderPayRecordPo.setTradeState(OrderPayRecordTradeStateEnum.REFUND_SUCCESS.getValue());
            } else if ("F".equals(transStat)) {
                tbOrderPayRecordPo.setTradeState(OrderPayRecordTradeStateEnum.REFUND_FAIL.getValue());
                tbOrderPayRecordPo.setRefundFailReason(JSON.toJSONString(dataObj));
            }

            tbOrderPayRecordPo.setRefundReqDate(reqDate);
            tbOrderPayRecordPo.setRefundReqSeqId(reqSeqId);
            tbOrderPayRecordPo.setRefundAmt(new BigDecimal(ordAmt));
            tbOrderPayRecordPo.setUpdateTime(LocalDateTime.now());
            orderPayRecordMapper.updateById(tbOrderPayRecordPo);
        }

        return true;
    }

    @Override
    public Boolean cancelPay(CancelPayDto cancelPayDto) {
        String orderNo = cancelPayDto.getOrderNo();
        if (StringUtils.isBlank(orderNo)) {
            Throw.isBusinessException("未找到订单数据");
        }

        List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                .eq("order_no", orderNo).eq("user_id", cancelPayDto.getUserId()));
        if (CollectionUtils.isEmpty(tbOrderPos)) {
            Throw.isBusinessException("未找到订单数据");
        }
        TbOrderPo tbOrderPo = tbOrderPos.get(0);

        Integer orderState = tbOrderPo.getOrderState();
        if (!OrderStateEnum.WAIT_PAY.getValue().equals(orderState)) {
            Throw.isBusinessException("只能取消待支付订单");
        }

        CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
        BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
        cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
        // 更新订单状态，待支付--》已关闭
        cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
        cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());

        if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
            Throw.isBusinessException("取消支付失败");
        }
        return true;
    }

    @Override
    public Page<AppOrderPageVo> pageAppOrder(AppOrderPageDto appOrderPageDto) {
        // 我购买的订单	 非经纪人且非策划人                          根据下单用户id=当前登录的userId查询
        // 我卖出的订单	 仅商家可见，显示商家发布的活动产生的订单         根据商家id=当前登录的商家id查询
        // 我分销的订单	 经纪人可见，显示经纪人分销出去的订单            根据经纪人id=当前登录的userId查询
        Integer orderSelectType = appOrderPageDto.getOrderSelectType();
        if (orderSelectType == null || OrderSelectTypeEnum.typeOf(orderSelectType) == null) {
            Throw.isBusinessException("请选择搜索订单类型");
        }

        List<Integer> orderStates = new ArrayList<>();
        // 处理订单状态
        // 前端显示订单状态(1 - 待支付, 2 - 待核销（包含待核销/核销中）, 3 - 已完成（包含已核销/已完成）, 4 - 已关闭（包含已取消/已关闭）)
        Integer orderState = appOrderPageDto.getOrderState();
        if (orderState != null) {
            if (FrontOrderStateEnum.WAIT_PAY.getValue().equals(orderState)) {
                orderStates.add(OrderStateEnum.WAIT_PAY.getValue());
            } else if (FrontOrderStateEnum.WAIT_VERIFY.getValue().equals(orderState)) {
                orderStates.add(OrderStateEnum.WAIT_VERIFY.getValue());
                orderStates.add(OrderStateEnum.VERIFYING.getValue());
            } else if (FrontOrderStateEnum.FINISH.getValue().equals(orderState)) {
                orderStates.add(OrderStateEnum.VERIFIED.getValue());
                orderStates.add(OrderStateEnum.FINISH.getValue());
            } else if (FrontOrderStateEnum.CLOSE.getValue().equals(orderState)) {
                orderStates.add(OrderStateEnum.CANCEL.getValue());
                orderStates.add(OrderStateEnum.CLOSE.getValue());
            } else {
                Throw.isBusinessException("请选择订单状态类型");
            }

            appOrderPageDto.setOrderState(null);
        }

        appOrderPageDto.setOrderStates(orderStates);

        Page<AppOrderPageVo> appOrderPageVoPage = OrderSelectFactory.getOrderSelectHandler(orderSelectType).pageAppOrder(appOrderPageDto);
        List<AppOrderPageVo> appOrderPageVos = appOrderPageVoPage.getList();

//        // 处理拼团信息
//        processGroupBuyOrderInfo(appOrderPageVos);

        if (!CollectionUtils.isEmpty(appOrderPageVos)) {
            for (AppOrderPageVo appOrderPageVo : appOrderPageVos) {
                if (!OrderStateEnum.PAYING.getValue().equals(appOrderPageVo.getOrderState())) {
                    continue;
                }

                // 如果存在支付中的订单，做查单处理
                // 调用hf查单接口，避免临界点出现支付情况，如果查单状态是支付成功，则修改状态为待核销
                HfTradeQuery hfTradeQuery = new HfTradeQuery();
                hfTradeQuery.setOrgReqDate(appOrderPageVo.getHfReqDate());
                hfTradeQuery.setOrgReqSeqId(appOrderPageVo.getHfReqSeqId());
                JSONObject jsonObject = hfApi.tradeQuery(hfTradeQuery).unpack();
                if (jsonObject != null) {
                    JSONObject dataJSONObject = jsonObject.getJSONObject("data");
                    // 交易状态	P：处理中；S：成功；F：失败；I: 初始（初始状态很罕见，请联系汇付技术人员处理）；
                    String transStat = dataJSONObject.getString("trans_stat");
                    // NOTPAY，订单未支付
                    String bankCode = dataJSONObject.getString("bank_code");
                    log.info("订单列表，查单成功，订单第三方交易状态：【{}】，orderNo：{}，bankCode：{}", transStat, appOrderPageVo.getOrderNo(), bankCode);
                    if ("S".equals(transStat)) {
                        PaySuccessOrderParam paySuccessOrderParam = new PaySuccessOrderParam();
                        paySuccessOrderParam.setId(appOrderPageVo.getId());
                        paySuccessOrderParam.setOrgOrderState(OrderStateEnum.PAYING.getValue());
                        paySuccessOrderParam.setBusinessId(appOrderPageVo.getBusinessId());
                        paySuccessOrderParam.setUserId(appOrderPageVo.getUserId());
                        paySuccessOrderParam.setOrderTime(appOrderPageVo.getOrderTime());
                        paySuccess(paySuccessOrderParam);
                    } else if ("P".equals(transStat)) {
                        if (!StringUtils.isBlank(bankCode) && "NOTPAY".equals(bankCode)) {
                            // 表示已唤醒支付，但未支付关闭第三方支付页面，将支付中--》待支付
                            OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                            orderStateUpdateParam.setId(appOrderPageVo.getId());
                            orderStateUpdateParam.setOrgOrderState(OrderStateEnum.PAYING.getValue());
                            // 如果活动已结束或订单超时，则关闭订单
                            if (appOrderPageVo.getEndTime().compareTo(LocalDateTime.now()) <= 0
                                    || appOrderPageVo.getOrderTime().plusMinutes(Constant.ORDER_DELAY_TIME).compareTo(LocalDateTime.now()) <= 0) {
                                orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                                // 订单备注=超时未支付,系统自动关闭
                                orderStateUpdateParam.setOrderNote(OrderNoteConstant.THREE);
                                orderStateUpdateParam.setCloseTime(LocalDateTime.now());
                            } else {
                                orderStateUpdateParam.setOrderState(OrderStateEnum.WAIT_PAY.getValue());
                            }

                            orderStateUpdateParam.setUpdateTime(LocalDateTime.now());
                            baseMapper.updateOrderState(orderStateUpdateParam);
                        }
                    } else if ("F".equals(transStat)) {
                        // 查单是支付失败，将支付中--》待支付
                        OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                        orderStateUpdateParam.setId(appOrderPageVo.getId());
                        orderStateUpdateParam.setOrgOrderState(OrderStateEnum.PAYING.getValue());
                        // 如果活动已结束或订单超时，则关闭订单
                        if (appOrderPageVo.getEndTime().compareTo(LocalDateTime.now()) <= 0
                                || appOrderPageVo.getOrderTime().plusMinutes(Constant.ORDER_DELAY_TIME).compareTo(LocalDateTime.now()) <= 0) {
                            orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                            // 订单备注=超时未支付,系统自动关闭
                            orderStateUpdateParam.setOrderNote(OrderNoteConstant.THREE);
                            orderStateUpdateParam.setCloseTime(LocalDateTime.now());
                        } else {
                            orderStateUpdateParam.setOrderState(OrderStateEnum.WAIT_PAY.getValue());
                        }

                        orderStateUpdateParam.setUpdateTime(LocalDateTime.now());
                        baseMapper.updateOrderState(orderStateUpdateParam);
                    }
                } else {
                    // 没有查到订单，将支付中--》待支付
                    OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                    orderStateUpdateParam.setId(appOrderPageVo.getId());
                    orderStateUpdateParam.setOrgOrderState(OrderStateEnum.PAYING.getValue());
                    // 如果活动已结束或订单超时，则关闭订单
                    if (appOrderPageVo.getEndTime().compareTo(LocalDateTime.now()) <= 0
                            || appOrderPageVo.getOrderTime().plusMinutes(Constant.ORDER_DELAY_TIME).compareTo(LocalDateTime.now()) <= 0) {
                        orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                        // 订单备注=超时未支付,系统自动关闭
                        orderStateUpdateParam.setOrderNote(OrderNoteConstant.THREE);
                        orderStateUpdateParam.setCloseTime(LocalDateTime.now());
                    } else {
                        orderStateUpdateParam.setOrderState(OrderStateEnum.WAIT_PAY.getValue());
                    }

                    orderStateUpdateParam.setUpdateTime(LocalDateTime.now());
                    baseMapper.updateOrderState(orderStateUpdateParam);
                }

            }
        }

        return OrderSelectFactory.getOrderSelectHandler(orderSelectType).pageAppOrder(appOrderPageDto);
    }

    // 拼团订单信息
    private void processGroupBuyOrderInfo(List<AppOrderPageVo> appOrderPageVos) {
        if (CollectionUtils.isEmpty(appOrderPageVos)) {
            return;
        }
        List<AppOrderPageVo> groupBuyOrderList = appOrderPageVos.stream()
                .filter(e -> PromotionTypeEnum.GROUP_BUY.name().equals(e.getPromotionType())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(groupBuyOrderList)) {
            return;
        }
        List<Long> orderIds = groupBuyOrderList.stream().map(AppOrderPageVo::getId).collect(Collectors.toList());
        List<GroupBuyOrderDetailVo> groupBuyOrderDetailVos = groupBuyOrderService.listDetailByOrderIds(orderIds);
        Map<Long, GroupBuyOrderDetailVo> orderIdToGroupDetailMap = groupBuyOrderDetailVos.stream()
                .collect(Collectors.toMap(GroupBuyOrderDetailVo::getOrderId, Function.identity()));
        for (AppOrderPageVo appOrderPageVo : appOrderPageVos) {
            GroupBuyOrderDetailVo groupBuyOrderDetailVo = orderIdToGroupDetailMap.get(appOrderPageVo.getId());
            appOrderPageVo.setGroupBuyOrderInfo(groupBuyOrderDetailVo);
        }
    }

    @Override
    public Page<MyPrizeOrderPageVo> pageMyPrizeOrder(MyPrizePageDto myPrizePageDto) {
        PageHelper.startPage(myPrizePageDto.getPageNum(), myPrizePageDto.getPageSize());
        List<MyPrizeOrderPageVo> orderPageVoList = baseMapper.pageMyPrizeOrder(myPrizePageDto);
        PageInfo<MyPrizeOrderPageVo> pageInfo = new PageInfo<>(orderPageVoList);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    @Override
    public AppOrderDetailVo appOrderDetail(AppOrderDetailDto appOrderDetailDto) {
        Integer orderSelectType = appOrderDetailDto.getOrderSelectType();
        if (orderSelectType == null || OrderSelectTypeEnum.typeOf(orderSelectType) == null) {
            Throw.isBusinessException("请选择搜索订单类型");
        }

        return OrderSelectFactory.getOrderSelectHandler(orderSelectType).appOrderDetail(appOrderDetailDto);
    }

    @Override
    public AppGroupBuyOrderDetailVo appGroupBuyOrderDetail(AppGroupBuyOrderDetailQueryDto appGroupBuyOrderDetailQueryDto) {
        return groupBuyOrderService.getAppGroupBuyOrderDetail(appGroupBuyOrderDetailQueryDto);
    }

    @Override
    public AppOrderEnrollActiveDetail appOrderEnrollActiveDetail(AppOrderEnrollActiveDetailDto appOrderEnrollActiveDetailDto) {
        Long id = appOrderEnrollActiveDetailDto.getId();
        if (id == null || id <= 0) {
            Throw.isBusinessException("未找到订单数据");
        }

        Long userId = appOrderEnrollActiveDetailDto.getUserId();
//        Long businessId = appOrderEnrollActiveDetailDto.getBusinessId();
//        if (businessId == null || businessId <= 0) {
        if (userId == null || userId <= 0) {
            Throw.isBusinessException(ResponseEnums.USER_ACCESS_DENIED);
        }
//
//            // 根据userId查询商家id
//            BusinessPageVo businessPageVo = businessApi.getByUserId(userId).unpack();
//            if (businessPageVo == null) {
//                // 如果不是商家，则返回空
//                Throw.isBusinessException(ResponseEnums.BUSINESS_ACCESS_DENIED);
//            }
//
//            businessId = businessPageVo.getId();
//            appOrderEnrollActiveDetailDto.setBusinessId(businessId);
//        }

        TbOrderPo tbOrderPo = baseMapper.selectById(id);
        if (tbOrderPo == null) {
            log.error("未找到订单数据，orderId：{}", id);
            Throw.isBusinessException("未找到订单数据");
        }

        if (!userId.equals(tbOrderPo.getUserId())) {
            log.error("未找到订单数据，订单不属于当前用户，orderId：{}，userId：{}，orderUserId：{}", id, userId, tbOrderPo.getUserId());
            Throw.isBusinessException("未找到订单数据");
        }

        // 1-待支付,2-待核销,3-核销中,4-已取消,5-已完成,6-已关闭
        Integer orderState = tbOrderPo.getOrderState();
        String orderNote = tbOrderPo.getOrderNote();
        Long activeId = tbOrderPo.getActiveId();
        ActiveVo activeVo = activeApi.getById(activeId).unpack();
        List<Integer> containEnrollActives = Arrays.asList(ActiveTypeEnum.ENROLL.getValue(), ActiveTypeEnum.GROUP_ENROLL.getValue());
        if (activeVo == null
                || ActiveStateEnum.NO_RELEASE.getValue().equals(activeVo.getActiveState())
                || !containEnrollActives.contains(activeVo.getActiveType())) {
            Throw.isBusinessException("未找到活动数据");
        }

        LocalDateTime now = LocalDateTime.now();

        Integer stepPriceState = activeVo.getStepPriceState();
        Integer noFullAutoRefundState = activeVo.getNoFullAutoRefundState();
        List<com.cq.hd.product.api.dto.ActiveStepPriceSonDto> activeStepPrices = activeVo.getActiveStepPrices();
        Integer totalStock = activeVo.getTotalStock();
        LocalDateTime startTime = activeVo.getStartTime();
        LocalDateTime endTime = activeVo.getEndTime();
        Integer activeState = activeVo.getActiveState();
        if (startTime.compareTo(now) > 0) {
            activeState = ActiveStateEnum.NO_START.getValue();
        } else if (endTime.compareTo(now) <= 0) {
            activeState = ActiveStateEnum.ENDED.getValue();
        } else if (startTime.compareTo(now) <= 0 && endTime.compareTo(now) > 0) {
            activeState = ActiveStateEnum.IN_PROGRESS.getValue();
        }

        if (ActiveStateEnum.NO_START.getValue().equals(activeState)) {
            Throw.isBusinessException("活动未开始");
        }

        //  如果是阶梯活动，处理活动价格
        if (StepPriceStateEnum.YES.getValue().equals(stepPriceState)) {
            // 根据活动id查询阶梯价格数据
            if (!CollectionUtils.isEmpty(activeStepPrices)) {
                // 倒序阶梯价格，获取阶梯最大价格
                activeStepPrices = activeStepPrices.stream()
                        .sorted(Comparator.comparing(com.cq.hd.product.api.dto.ActiveStepPriceSonDto::getEnrollPrice).reversed())
                        .collect(Collectors.toList());
                activeVo.setActivePrice(activeStepPrices.get(0).getEnrollPrice());
            }
        }

        // 还差x人即可开启活动/再邀x人，可返33.5元/已满x人，可返33.5元/未集齐人数，已自动退款/小伙伴们在等你呢，快来呀~等文字
        String title = "";
        // 已有y人参团
        String subTitle = "";
        // 按钮状态:0-没有按钮,1-邀请好友,2-查看订单,3-去支付
        int buttonState = 0;
        // 报名用户头像
        List<String> avatars = new ArrayList<>();
        // 已报名人数
        int enrolledNum = 0;
        // 显示报名用户头像个数
        int avatarNum = 10;
        // 还差x人/再邀x人/已满x人
        int inviteNum = 0;
        // 再邀x人,可返y元/已满x人,可返y元
        BigDecimal returnAmt = BigDecimal.ZERO;
        List<TbOrderItemPo> enrolledOrderItems = new ArrayList<>();

        // 查询当前活动报名的人数
        List<TbOrderItemPo> activeEnrollOrderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                .eq("active_id", activeId).in("sub_order_state", Arrays.asList(SubOrderStateEnum.WAIT_PAY.getValue(),
                        SubOrderStateEnum.WAIT_VERIFY.getValue(), SubOrderStateEnum.VERIFIED.getValue(),
                        SubOrderStateEnum.CANCEL.getValue())).isNotNull("enroll_info"));
        if (!CollectionUtils.isEmpty(activeEnrollOrderItemPos)) {
            // 过滤符合报名条件的用户（只要在活动结束前没取消的都算，活动结束后取消也算）
            for (TbOrderItemPo orderItemPo : activeEnrollOrderItemPos) {
                // 如果用户取消参与活动，且活动结束时间不早于取消活动时间，则不计入报名用户数
                if (SubOrderStateEnum.CANCEL.getValue().equals(orderItemPo.getSubOrderState())
                        && endTime.compareTo(orderItemPo.getCancelTime()) >= 0) {
                    continue;
                }

                enrolledNum += 1;
                enrolledOrderItems.add(orderItemPo);
            }
        }


        // 副标题:已有x人报名
        subTitle = String.format("已有%s人报名", enrolledNum);

        if (NoFullAutoRefundStateEnum.YES.getValue().equals(noFullAutoRefundState)) {
            // 开启未满自动退

            // 固定人数
            // 未满,未结束,主标题:还差x人即可开启活动        邀请好友
            // 未满,已结束,主标题:未集齐人数,已自动退款      查看订单
            // 已满,未结束,主标题:恭喜您报名成功            查看订单
            // 已满,已结束,主标题:恭喜您报名成功            查看订单

            // 阶梯人数
            // 未满一阶梯,未结束,主标题:还差x人即可开启活动     邀请好友
            // 未满一阶梯,已结束,主标题:未集齐人数,已自动退款   查看订单
            // 已满一阶梯、未到最高，未结束: 再邀请x人，可返y元--邀请好友
            // 已满一阶梯、未到二阶，已结束: 恭喜您报名成功--查看订单
            // 已满二阶梯，已结束: 已满x人，可返y元--查看订单

            if (StepPriceStateEnum.YES.getValue().equals(stepPriceState)) {
                // 根据阶梯报名人数正序
                activeStepPrices = activeStepPrices.stream()
                        .sorted(Comparator.comparing(com.cq.hd.product.api.dto.ActiveStepPriceSonDto::getEnrollNum))
                        .collect(Collectors.toList());

                // 阶梯最小人数
                Integer firstEnrollNum = activeStepPrices.get(0).getEnrollNum();
                if (enrolledNum < firstEnrollNum) {
                    if (ActiveStateEnum.IN_PROGRESS.getValue().equals(activeState)) {
                        // 未满一阶梯,未结束,主标题:还差x人即可开启活动     邀请好友

                        inviteNum = firstEnrollNum - enrolledNum;
                        title = String.format("还差%s人即可开启活动", inviteNum);
                        // 显示邀请好友按钮
                        buttonState = 1;
                        avatarNum = 9;
                    } else if (ActiveStateEnum.ENDED.getValue().equals(activeState)) {
                        // 未满一阶梯,已结束,主标题:未集齐人数,已自动退款   查看订单

                        title = "未集齐人数,已自动退款";
                        // 显示查看订单按钮
                        buttonState = 2;
                        avatarNum = 9;
                    }
                } else {
                    // 已达最小人数阶梯，未达下一阶梯

                    // 阶梯最多人数
                    Integer lastEnrollNum = activeStepPrices.get(activeStepPrices.size() - 1).getEnrollNum();

                    if (ActiveStateEnum.IN_PROGRESS.getValue().equals(activeState)) {
                        for (com.cq.hd.product.api.dto.ActiveStepPriceSonDto activeStepPrice : activeStepPrices) {
                            Integer enrollNum = activeStepPrice.getEnrollNum();
                            BigDecimal enrollPrice = activeStepPrice.getEnrollPrice();

                            // 取下一阶级的报名人数对比，如果都没匹配上，则表示已满员
                            if (enrolledNum < enrollNum) {
                                // 计算再邀人数=下一阶级报名人数-已报名人数
                                inviteNum = enrollNum - enrolledNum;
                                // 计算可返金额=当前报名价格-对应阶级报名价格
                                returnAmt = tbOrderPo.getActivePrice().subtract(enrollPrice);
                                break;
                            }
                        }

                        if (enrolledNum < lastEnrollNum) {
                            // 已满一阶梯、未到最高,未结束,主标题:再邀请x人,可返y元      邀请好友

                            if (returnAmt.compareTo(BigDecimal.ZERO) > 0) {
                                title = String.format("再邀%s人，核销可返%s元", inviteNum, returnAmt);
                            } else {
                                title = String.format("再邀%s人", inviteNum);
                            }
                            // 显示邀请好友按钮
                            buttonState = 1;
                            avatarNum = 9;
                        }
                    } else if (ActiveStateEnum.ENDED.getValue().equals(activeState)) {

                        if (activeStepPrices.size() > 1) {
                            // 二阶
                            Integer secondEnrollNum = activeStepPrices.get(1).getEnrollNum();
                            if (enrolledNum < secondEnrollNum) {
                                // 已满一阶梯、未到二阶，已结束: 恭喜您报名成功--查看订单

                                title = "恭喜您报名成功";
                                // 显示查看订单按钮
                                buttonState = 2;
                                avatarNum = 9;
                            } else {
                                // 二阶报名价格
                                BigDecimal secondEnrollPrice = activeStepPrices.get(1).getEnrollPrice();
                                returnAmt = tbOrderPo.getActivePrice().subtract(secondEnrollPrice);

                                // 已满二阶梯，已结束: 已满x人，可返y元--查看订单
                                if (returnAmt.compareTo(BigDecimal.ZERO) > 0) {
                                    title = String.format("已满%s人，核销可返%s元", enrolledNum, returnAmt);
                                } else {
                                    title = String.format("已满%s人", enrolledNum);
                                }
                                // 显示查看订单按钮
                                buttonState = 2;
                                avatarNum = 9;
                            }
                        }

//                        for (com.cq.hd.product.api.dto.ActiveStepPriceSonDto activeStepPrice : activeStepPrices) {
//                            Integer enrollNum = activeStepPrice.getEnrollNum();
//                            BigDecimal enrollPrice = activeStepPrice.getEnrollPrice();
//
//                            // 取上一阶级的报名人数对比，如果都没匹配上，则表示已满员
//                            if (enrolledNum >= enrollNum) {
//                                // 计算再邀人数=下一阶级报名人数-已报名人数
//                                inviteNum = enrollNum - enrolledNum;
//                                // 计算可返金额=当前报名价格-对应阶级报名价格
//                                returnAmt = tbOrderPo.getActivePrice().subtract(enrollPrice);
//                                break;
//                            }
//                        }
//
//                        if (returnAmt.compareTo(BigDecimal.ZERO) > 0) {
//                            title = String.format("已满%s人，可返%s元", enrolledNum, returnAmt);
//                        } else {
//                            title = String.format("已满%s人", enrolledNum);
//                        }
//                        // 显示查看订单按钮
//                        buttonState = 2;
//                        avatarNum = 9;
                    }
                }
            } else {
                if (totalStock > enrolledNum) {
                    if (ActiveStateEnum.IN_PROGRESS.getValue().equals(activeState)) {
                        // 未满,未结束,主标题:还差x人即可开启活动        邀请好友

                        title = String.format("还差%s人即可开启活动", totalStock - enrolledNum);
                        // 显示邀请好友按钮
                        buttonState = 1;
                        avatarNum = 9;
                    } else if (ActiveStateEnum.ENDED.getValue().equals(activeState)) {
                        // 未满,已结束,主标题:未集齐人数,已自动退款      查看订单

                        title = "未集齐人数,已自动退款";
                        // 显示查看订单按钮
                        buttonState = 2;
                        avatarNum = 9;
                    }
                } else {
                    // 已满,未结束,主标题:恭喜您报名成功            查看订单
                    // 已满,已结束,主标题:恭喜您报名成功            查看订单

                    title = "恭喜您报名成功";
                    // 显示查看订单按钮
                    buttonState = 2;
                    avatarNum = 10;
                }
            }
        } else {
            // 关闭未满自动退,未满不退

            // 固定人数
            // 未满,未结束,主标题:还差x人即可开启活动           邀请好友
            // 未满,已结束,主标题:恭喜您报名成功               查看订单
            // 已满,未结束,主标题:恭喜您报名成功               查看订单
            // 已满,已结束,主标题:恭喜您报名成功               查看订单

            // 阶梯人数
            // 未满一阶梯,未结束,主标题:还差x人即可开启活动        邀请好友
            // 未满一阶梯,已结束,主标题:恭喜您报名成功            查看订单
            // 已满一阶梯、未到最高，未结束: 再邀请x人，可返y元--邀请好友
            // 已满一阶梯、未到二阶，已结束: 恭喜您报名成功--查看订单
            // 已满二阶梯，已结束:已满x人，可返y元--查看订单

            if (StepPriceStateEnum.YES.getValue().equals(stepPriceState)) {
                // 根据阶梯报名人数正序
                activeStepPrices = activeStepPrices.stream()
                        .sorted(Comparator.comparing(com.cq.hd.product.api.dto.ActiveStepPriceSonDto::getEnrollNum))
                        .collect(Collectors.toList());

                // 阶梯最小人数
                Integer firstEnrollNum = activeStepPrices.get(0).getEnrollNum();
                if (enrolledNum < firstEnrollNum) {
                    if (ActiveStateEnum.IN_PROGRESS.getValue().equals(activeState)) {
                        // 未满一阶梯,未结束,主标题:还差x人即可开启活动        邀请好友

                        inviteNum = firstEnrollNum - enrolledNum;
                        title = String.format("还差%s人即可开启活动", inviteNum);
                        // 显示邀请好友按钮
                        buttonState = 1;
                        avatarNum = 9;
                    } else if (ActiveStateEnum.ENDED.getValue().equals(activeState)) {
                        // 未满一阶梯,已结束,主标题:恭喜您报名成功            查看订单

                        title = "恭喜您报名成功";
                        // 显示查看订单按钮
                        buttonState = 2;
                        avatarNum = 9;
                    }
                } else {
                    // 已达最小人数阶梯，未达下一阶梯

                    // 阶梯最多人数
                    Integer lastEnrollNum = activeStepPrices.get(activeStepPrices.size() - 1).getEnrollNum();

                    if (ActiveStateEnum.IN_PROGRESS.getValue().equals(activeState)) {
                        for (com.cq.hd.product.api.dto.ActiveStepPriceSonDto activeStepPrice : activeStepPrices) {
                            Integer enrollNum = activeStepPrice.getEnrollNum();
                            BigDecimal enrollPrice = activeStepPrice.getEnrollPrice();

                            // 取下一阶级的报名人数对比，如果都没匹配上，则表示已满员
                            if (enrolledNum < enrollNum) {
                                // 计算再邀人数=下一阶级报名人数-已报名人数
                                inviteNum = enrollNum - enrolledNum;
                                // 计算可返金额=当前报名价格-对应阶级报名价格
                                returnAmt = tbOrderPo.getActivePrice().subtract(enrollPrice);
                                break;
                            }
                        }

                        if (enrolledNum < lastEnrollNum) {
                            // 已满一阶梯、未到最高,未结束,主标题:再邀请x人,可返y元      邀请好友

                            if (returnAmt.compareTo(BigDecimal.ZERO) > 0) {
                                title = String.format("再邀%s人，核销可返%s元", inviteNum, returnAmt);
                            } else {
                                title = String.format("再邀%s人", inviteNum);
                            }
                            // 显示邀请好友按钮
                            buttonState = 1;
                            avatarNum = 9;
                        }
                    } else if (ActiveStateEnum.ENDED.getValue().equals(activeState)) {
                        if (activeStepPrices.size() > 1) {
                            // 二阶
                            Integer secondEnrollNum = activeStepPrices.get(1).getEnrollNum();
                            if (enrolledNum < secondEnrollNum) {
                                // 已满一阶梯、未到二阶，已结束: 恭喜您报名成功--查看订单

                                title = "恭喜您报名成功";
                                // 显示查看订单按钮
                                buttonState = 2;
                                avatarNum = 9;
                            } else {
                                // 二阶报名价格
                                BigDecimal secondEnrollPrice = activeStepPrices.get(1).getEnrollPrice();
                                returnAmt = tbOrderPo.getActivePrice().subtract(secondEnrollPrice);

                                // 已满二阶梯，已结束: 已满x人，可返y元--查看订单
                                if (returnAmt.compareTo(BigDecimal.ZERO) > 0) {
                                    title = String.format("已满%s人，核销可返%s元", enrolledNum, returnAmt);
                                } else {
                                    title = String.format("已满%s人", enrolledNum);
                                }
                                // 显示查看订单按钮
                                buttonState = 2;
                                avatarNum = 9;
                            }
                        }
                    }
                }
            } else {
                if (totalStock > enrolledNum) {
                    if (ActiveStateEnum.IN_PROGRESS.getValue().equals(activeState)) {
                        // 未满,未结束,主标题:还差x人即可开启活动           邀请好友

//                        title = String.format("还差%s人即可开启活动", totalStock - enrolledNum);
                        title = "恭喜您报名成功";
                        // 显示邀请好友按钮
                        buttonState = 1;
                        avatarNum = 9;
                    } else if (ActiveStateEnum.ENDED.getValue().equals(activeState)) {
                        // 未满,已结束,主标题:恭喜您报名成功               查看订单

                        title = "恭喜您报名成功";
                        // 显示邀请好友按钮
                        buttonState = 1;
                        avatarNum = 9;
                    }
                } else {
                    // 已满,未结束,主标题:恭喜您报名成功            查看订单
                    // 已满,已结束,主标题:恭喜您报名成功            查看订单

                    title = "恭喜您报名成功";
                    // 显示查看订单按钮
                    buttonState = 2;
                    avatarNum = 10;
                }
            }
        }

        List<Long> userIds;
        if (enrolledNum > avatarNum) {
            userIds = enrolledOrderItems.subList(0, avatarNum).stream()
                    .map(TbOrderItemPo::getUserId).collect(Collectors.toList());
        } else {
            userIds = enrolledOrderItems.stream()
                    .map(TbOrderItemPo::getUserId).collect(Collectors.toList());
        }

        if (!CollectionUtils.isEmpty(userIds)) {
            List<AppUserVo> appUserVos = appUserApi.listByUserIds(userIds).unpack();
            if (!CollectionUtils.isEmpty(appUserVos)) {
                avatars = appUserVos.stream().map(AppUserVo::getAvatar).collect(Collectors.toList());
            }
        }

        AppOrderEnrollActiveDetail appOrderEnrollActiveDetail = new AppOrderEnrollActiveDetail();
        BeanUtils.copyProperties(activeVo, appOrderEnrollActiveDetail);
        appOrderEnrollActiveDetail.setActiveStepPrices(JSON.parseArray(JSON.toJSONString(activeVo.getActiveStepPrices()), ActiveStepPriceSonDto.class));
        appOrderEnrollActiveDetail.setOrderId(tbOrderPo.getId());
        appOrderEnrollActiveDetail.setTitle(title);
        appOrderEnrollActiveDetail.setSubTitle(subTitle);
        appOrderEnrollActiveDetail.setButtonState(buttonState);
        appOrderEnrollActiveDetail.setAvatars(avatars);
        appOrderEnrollActiveDetail.setInviteNum(inviteNum);
        appOrderEnrollActiveDetail.setReturnAmt(returnAmt);
        appOrderEnrollActiveDetail.setEnrolledNum(enrolledNum);
        return appOrderEnrollActiveDetail;
    }

    @Override
    public Boolean cancelOrder(CancelOrderDto cancelOrderDto) {
        Long orderId = cancelOrderDto.getOrderId();
        if (orderId == null || orderId <= 0) {
            Throw.isBusinessException("未找到订单数据");
        }

        // 对订单id加锁
        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "cancelOrder:" + orderId);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                    .eq("id", orderId).eq("user_id", cancelOrderDto.getUserId()));
            if (CollectionUtils.isEmpty(tbOrderPos)) {
                Throw.isBusinessException("未找到订单数据");
            }
            TbOrderPo tbOrderPo = tbOrderPos.get(0);

            // 待支付、待核销才能取消
            Set<Integer> allowCancelState = Stream.of(OrderStateEnum.WAIT_PAY.getValue(),
                            OrderStateEnum.WAIT_VERIFY.getValue(), OrderStateEnum.WAIT_GROUP.getValue())
                    .collect(Collectors.toSet());
            if (!allowCancelState.contains(tbOrderPo.getOrderState())) {
                Throw.isBusinessException("当前状态无法取消");
            }

            CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
            BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
            cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
            if (OrderStateEnum.WAIT_VERIFY.getValue().equals(tbOrderPo.getOrderState())) {
                // 更新订单状态，待核销--》已取消
                cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CANCEL.getValue());
                cancelWaitPayOrVerifyOrderParam.setCancelTime(LocalDateTime.now());
                // 订单备注=用户申请退款
                cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.TWO);
            } else if (OrderStateEnum.WAIT_PAY.getValue().equals(tbOrderPo.getOrderState())) {
                // 更新订单状态，待支付--》已关闭
                cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
                cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                // 订单备注=超时未支付,系统自动关闭
                cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.NINE);
                cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());
            } else if (OrderStateEnum.WAIT_GROUP.getValue().equals(tbOrderPo.getOrderState())
                    // 待成团 + 拼团失败
                    && Objects.equals(cancelOrderDto.getRefundType(), RefundTypeEnum.GROUP_FAILED.getValue())) {
                // 更新订单状态，待成团--》已关闭
                cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
                cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                // 订单备注=超时未支付,系统自动关闭
                cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.ELEVEN);
                cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());
                cancelWaitPayOrVerifyOrderParam.setRefundType(cancelOrderDto.getRefundType());
            } else if (OrderStateEnum.WAIT_GROUP.getValue().equals(tbOrderPo.getOrderState())) {
                // 更新订单状态，待成团--》已取消
                cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CANCEL.getValue());
                cancelWaitPayOrVerifyOrderParam.setCancelTime(LocalDateTime.now());
                // 订单备注=用户申请退款
                cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.TWO);
            }

            if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
                Throw.isBusinessException("取消订单失败");
            }

            List<TbOrderRefundPo> tbOrderRefundPos = orderRefundMapper.selectList(new QueryWrapper<TbOrderRefundPo>().eq("del_state", 0)
                    .eq("order_id", tbOrderPo.getId()));
            if (!CollectionUtils.isEmpty(tbOrderRefundPos)) {
                // 待核销订单,发送mq异步退款
                orderRefundMsgProvider.sendMsg(tbOrderRefundPos.get(0).getId());
            }

            return true;
        } finally {
            LockUtils.unlock(lockKey);
        }
    }

    public Long cancelOrderPft(Long orderId) {
        // 对订单id加锁
        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "cancelOrder:" + orderId);
        try {
            TbOrderPo tbOrderPo = baseMapper.selectById(orderId);
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            if (!OrderStateEnum.WAIT_VERIFY.getValue().equals(tbOrderPo.getOrderState())) {
                Throw.isBusinessException("只能取消待核销的订单");
            }

            CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
            BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
            cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
            // 更新订单状态，待核销--》已取消
            cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CANCEL.getValue());
            cancelWaitPayOrVerifyOrderParam.setCancelTime(LocalDateTime.now());
            // 订单备注=用户申请退款
            cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.SIX);
            if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
                Throw.isBusinessException("取消订单失败");
            }

            List<TbOrderRefundPo> tbOrderRefundPos = orderRefundMapper.selectList(new QueryWrapper<TbOrderRefundPo>().eq("del_state", 0)
                    .eq("order_id", tbOrderPo.getId()));
            if (!CollectionUtils.isEmpty(tbOrderRefundPos)) {
                // 待核销订单,发送mq异步退款
                return tbOrderRefundPos.get(0).getId();
            }

            return null;
        } finally {
            LockUtils.unlock(lockKey);
        }
    }

    @Override
    public Boolean cancelWaitPayOrVerifyOrder(CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam) {
        Long orderId = cancelWaitPayOrVerifyOrderParam.getId();
        Integer orderType = cancelWaitPayOrVerifyOrderParam.getOrderType();
        Integer refundType = cancelWaitPayOrVerifyOrderParam.getRefundType(); // 拼团失败会传值

        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "cancelWaitPayOrVerifyOrder:" + orderId);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            List<TbOrderItemPo> tbOrderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                    .eq("order_id", orderId));

            LocalDateTime now = LocalDateTime.now();

            ActiveRedPacketBillPageVo activeRedPacketBillPageVo = null;
            Long redPacketBillId = cancelWaitPayOrVerifyOrderParam.getRedPacketBillId();
            if (redPacketBillId != null && redPacketBillId > 0) {
                activeRedPacketBillPageVo = activeRedPacketBillApi.getById(redPacketBillId).unpack();

                // 如果活动已结束,则不用处理,如果活动未结束,判断红包是否过期,如果过期,则修改为过期,如果有效,修改为未使用
                LocalDateTime endTime = cancelWaitPayOrVerifyOrderParam.getEndTime();
                if (now.isBefore(endTime)) {
                    // 活动未结束
                    LocalDateTime expireTime = activeRedPacketBillPageVo.getExpireTime();
                    // 判断红包是否过期,如果过期,则修改为过期,如果有效,修改为未使用
                    activeRedPacketBillPageVo.setState(now.isBefore(expireTime)
                            ? ActiveRedPacketStateEnum.NO_USE.getValue()
                            : ActiveRedPacketStateEnum.YES_EXPIRE.getValue());
                }
            }

            OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
            orderStateUpdateParam.setId(orderId);
            orderStateUpdateParam.setOrgOrderState(cancelWaitPayOrVerifyOrderParam.getOrgOrderState());
            orderStateUpdateParam.setOrderState(cancelWaitPayOrVerifyOrderParam.getOrderState());
            orderStateUpdateParam.setOrderNote(cancelWaitPayOrVerifyOrderParam.getOrderNote());
            if (OrderStateEnum.CANCEL.getValue().equals(cancelWaitPayOrVerifyOrderParam.getOrderState())) {
                orderStateUpdateParam.setCancelTime(cancelWaitPayOrVerifyOrderParam.getCancelTime());
            } else if (OrderStateEnum.CLOSE.getValue().equals(cancelWaitPayOrVerifyOrderParam.getOrderState())) {
                orderStateUpdateParam.setCloseTime(cancelWaitPayOrVerifyOrderParam.getCloseTime());
            }

            TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

            try {
                // 如果是取消支付，更新订单状态，由待支付-》已关闭
                // 如果是取消订单，更新订单状态，由待核销-》已取消
                // 如果是消费延时消息，更新订单状态，由待支付-》已关闭
                // 如果是系统取消支付，更新订单状态，由待支付-》已关闭
                int update = baseMapper.updateOrderState(orderStateUpdateParam);
                if (update == 0) {
                    Throw.isBusinessException("取消失败");
                }

                // 将订单项的子订单设置为已取消
                update = orderItemMapper.updateCancelByOrderId(orderId, now);
                if (update == 0) {
                    Throw.isBusinessException("取消失败");
                }

                if (Objects.equals(orderType, ActiveTypeEnum.POINTS.getValue())) {
                    boolean res = businessPointsMallApi.cancelOrderSendBackPoints(orderId).unpack();
                    if (!res) {
                        Throw.isBusinessException("取消失败[points]");
                    }
                } else {
                    cancelActiveOrder(tbOrderItemPos, cancelWaitPayOrVerifyOrderParam, activeRedPacketBillPageVo);
                }

                // 拼团订单取消，扣除占用的成团名额
                String promotionType = cancelWaitPayOrVerifyOrderParam.getPromotionType();
                if (PromotionTypeEnum.GROUP_BUY.name().equals(promotionType)
                        // 拼团失败过来的，因为在调用处已经取消，不再重复取消拼团订单
                        && !cancelWaitPayOrVerifyOrderParam.getOrderNote().equals(OrderNoteConstant.ELEVEN)) {
                    groupBuyOrderService.cancel(orderId);
                }

                transactionManager.commit(transaction);
            } catch (Exception e) {
                //回滚事务
                transactionManager.rollback(transaction);
                log.error("<取消活动订单>事务异常回滚", e);
                return false;
            }

        } finally {
            LockUtils.unlock(lockKey);
        }

        return true;
    }

    private void cancelActiveOrder(List<TbOrderItemPo> tbOrderItemPos, CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam, ActiveRedPacketBillPageVo activeRedPacketBillPageVo) {
        Map<String, List<ActiveGoodsSonDto>> activeGoodsSonDtoMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(tbOrderItemPos)) {
            for (TbOrderItemPo tbOrderItemPo : tbOrderItemPos) {
                Integer mulState = tbOrderItemPo.getMulState();
                String goodsId = tbOrderItemPo.getGoodsId();

                if (MulStateEnum.NO.getValue().equals(mulState) && !StringUtils.isBlank(goodsId)) {
                    List<ActiveGoodsSonDto> activeGoodsSonDtoList = activeGoodsSonDtoMap.get(goodsId);
                    if (CollectionUtils.isEmpty(activeGoodsSonDtoList)) {
                        activeGoodsSonDtoList = new ArrayList<>();
                    }

                    ActiveGoodsSonDto activeGoodsSonDto = new ActiveGoodsSonDto();
                    activeGoodsSonDto.setGoodsId(goodsId);
                    activeGoodsSonDto.setGoodsNum(1);
                    activeGoodsSonDtoList.add(activeGoodsSonDto);
                    activeGoodsSonDtoMap.put(goodsId, activeGoodsSonDtoList);
                }
            }
        }

        List<ActiveGoodsSonDto> activeGoodsSonDtos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(activeGoodsSonDtoMap)) {
            for (List<ActiveGoodsSonDto> value : activeGoodsSonDtoMap.values()) {
                activeGoodsSonDtos.addAll(value);
            }
        }

        ActiveAddStockDto activeAddStockDto = new ActiveAddStockDto();
        activeAddStockDto.setActiveId(cancelWaitPayOrVerifyOrderParam.getActiveId());
        activeAddStockDto.setNum(cancelWaitPayOrVerifyOrderParam.getOrderNum());
        activeAddStockDto.setActiveRedPacketBillPageVo(activeRedPacketBillPageVo);
        activeAddStockDto.setActiveGoodsSonDtos(activeGoodsSonDtos);
        // 增加活动库存和活动商品库存，将红包退还，并设置红包为未使用状态
        boolean addResult = activeApi.addActiveStock(activeAddStockDto).unpack();
        if (!addResult) {
            Throw.isBusinessException("取消失败");
        }

        // 如果是已支付待核销的订单取消，则需要增加订单退款记录数据，退款交易状态=待处理
        Integer orgOrderState = cancelWaitPayOrVerifyOrderParam.getOrgOrderState();
        if (OrderStateEnum.CANCEL.getValue().equals(cancelWaitPayOrVerifyOrderParam.getOrderState())
                || (OrderStateEnum.CLOSE.getValue().equals(cancelWaitPayOrVerifyOrderParam.getOrderState()) && OrderStateEnum.WAIT_GROUP.getValue().equals(orgOrderState))) {
            TbOrderRefundPo tbOrderRefundPo = new TbOrderRefundPo();
            tbOrderRefundPo.setBusinessId(cancelWaitPayOrVerifyOrderParam.getBusinessId());
            tbOrderRefundPo.setUserId(cancelWaitPayOrVerifyOrderParam.getUserId());
            tbOrderRefundPo.setOrderId(cancelWaitPayOrVerifyOrderParam.getId());
            // 退款类型(1-用户申请退款，2-核销过期自动退)
            if (cancelWaitPayOrVerifyOrderParam.getOrderNote().equals(OrderNoteConstant.SIX)) {
                tbOrderRefundPo.setRefundType(RefundTypeEnum.PFT_REFUND.getValue());
            } else if (RefundTypeEnum.GROUP_FAILED.getValue().equals(cancelWaitPayOrVerifyOrderParam.getRefundType())){
                tbOrderRefundPo.setRefundType(RefundTypeEnum.GROUP_FAILED.getValue());
            } else {
                tbOrderRefundPo.setRefundType(RefundTypeEnum.USER_REFUND.getValue());
            }
            tbOrderRefundPo.setOrgReqDate(cancelWaitPayOrVerifyOrderParam.getHfReqDate());
            tbOrderRefundPo.setOrgReqSeqId(cancelWaitPayOrVerifyOrderParam.getHfReqSeqId());
            tbOrderRefundPo.setRefundAmt(cancelWaitPayOrVerifyOrderParam.getPayPrice());
            // 退款交易状态(1-待处理，2-处理中，3-成功，4-失败)
            tbOrderRefundPo.setRefundState(OrderRefundStateEnum.WAIT.getValue());
            tbOrderRefundPo.setRefundApplyTime(LocalDateUtil.getNowLocalDateTime());

            int insert = orderRefundMapper.insert(tbOrderRefundPo);
            if (insert == 0) {
                Throw.isBusinessException("取消失败");
            }
        }
    }

    @Override
    public Boolean confirmJoin(ConfirmJoinDto confirmJoinDto) {
        Long orderId = confirmJoinDto.getOrderId();
        if (orderId == null || orderId <= 0) {
            Throw.isBusinessException("未找到订单数据");
        }

        String verifyCode = confirmJoinDto.getVerifyCode();
        if (StringUtils.isBlank(verifyCode)) {
            Throw.isBusinessException("请选择确认参与的核销码");
        }

        // 对核销码加锁
        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "confirmJoin:" + verifyCode);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                    .eq("id", orderId).eq("user_id", confirmJoinDto.getUserId()));
            if (CollectionUtils.isEmpty(tbOrderPos)) {
                Throw.isBusinessException("未找到订单数据");
            }
            TbOrderPo tbOrderPo = tbOrderPos.get(0);
            LocalDateTime endTime = tbOrderPo.getEndTime();
            Long activeId = tbOrderPo.getActiveId();
            Integer orderState = tbOrderPo.getOrderState();
            // 核销方式(1-线上核销，2-线下核销)
            Integer verifyMethod = tbOrderPo.getVerifyMethod();
            // 订单类型(1-团购订单,2-报名订单,4-团购+报名订单,5积分订单)
            Integer orderType = tbOrderPo.getOrderType();
            // 未满员是否自动退款(报名订单):1-是，2-否
            Integer noFullAutoRefundState = tbOrderPo.getNoFullAutoRefundState();
            LocalDateTime validStartTime = tbOrderPo.getValidStartTime();
            LocalDateTime validEndTime = tbOrderPo.getValidEndTime();
            LocalDateTime now = LocalDateTime.now();

            // 只能是报名订单才可以确认参与
            if (!ActiveTypeEnum.ENROLL.getValue().equals(orderType)) {
                Throw.isBusinessException("只能确认参与报名订单");
            }

            // 只能确认参与线上核销的报名活动订单
            if (!VerifyMethodEnum.ON_LINE.getValue().equals(verifyMethod)) {
                Throw.isBusinessException("只能确认参与线上核销的报名订单");
            }

            // 报名活动开启未满员自动退，活动未结束不可核销
            if (NoFullAutoRefundStateEnum.YES.getValue().equals(noFullAutoRefundState)) {
                if (!now.isAfter(endTime)) {
                    Throw.isBusinessException("请于" + LocalDateUtil.toLocalDateTimeToString(endTime, Constant.YYYY_MM_DD_HH_MM_SS) + "后核销");
                }
            }

            if (now.isBefore(validStartTime)) {
                Throw.isBusinessException("请于" + LocalDateUtil.toLocalDateTimeToString(validStartTime, Constant.YYYY_MM_DD_HH_MM_SS) + "后核销");
            }

            if (now.isAfter(validEndTime)) {
                Throw.isBusinessException("已过活动核销时间");
            }

            if (OrderStateEnum.WAIT_PAY.getValue().equals(orderState)) {
                Throw.isBusinessException("不能参与待支付的订单");
            }

            // 已取消/已关闭的订单不能确认参与
            if (OrderStateEnum.CANCEL.getValue().equals(orderState) || OrderStateEnum.CLOSE.getValue().equals(orderState)) {
                Throw.isBusinessException("已取消的订单不能确认参与");
            }

            List<TbOrderItemPo> tbOrderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                    .eq("order_id", orderId));
            if (CollectionUtils.isEmpty(tbOrderItemPos)) {
                Throw.isBusinessException("未找到订单数据");
            }

            // 是否存在未核销的订单（过滤排除当前核销的订单项，且是待核销的订单项列表, 为空表示不存在未核销的订单项）
            boolean existNoVerifyOrder = !CollectionUtils.isEmpty(tbOrderItemPos.stream()
                    .filter(orderItemPo -> (!orderItemPo.getVerifyCode().equals(verifyCode)
                            && SubOrderStateEnum.WAIT_VERIFY.getValue().equals(orderItemPo.getSubOrderState())))
                    .collect(Collectors.toList()));

            List<TbOrderItemPo> tbOrderItemPosByActiveId = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                    .eq("active_id", activeId));
            if (CollectionUtils.isEmpty(tbOrderItemPosByActiveId)) {
                Throw.isBusinessException("未找到订单数据");
            }

            // 报名成功的用户订单（包含取消时间晚于活动结束时间的取消参与用户）
            List<TbOrderItemPo> enrolledSuccessOrderItems = new ArrayList<>();
            TbOrderItemPo currentOrderItemPo = null;
            for (TbOrderItemPo tbOrderItemPo : tbOrderItemPosByActiveId) {
                if (tbOrderItemPo.getVerifyCode().equals(verifyCode)) {
                    currentOrderItemPo = tbOrderItemPo;
                }

                // 如果是报名活动，则核销必须要等活动结束之后才能开始核销
                // 报名活动开启未满员自动退，活动未结束不可核销
                if (NoFullAutoRefundStateEnum.YES.getValue().equals(noFullAutoRefundState)) {
                    if (!now.isAfter(endTime)) {
                        Throw.isBusinessException("请于" + LocalDateUtil.toLocalDateTimeToString(validStartTime, Constant.YYYY_MM_DD_HH_MM_SS) + "后核销");
                    }
                }

                // 如果用户取消参与活动，且活动结束时间不早于取消活动时间，则不计入报名用户数
                if (SubOrderStateEnum.CANCEL.getValue().equals(tbOrderItemPo.getSubOrderState())
                        && endTime.compareTo(tbOrderItemPo.getCancelTime()) >= 0) {
                    continue;
                }

                enrolledSuccessOrderItems.add(tbOrderItemPo);
            }

            if (currentOrderItemPo == null) {
                Throw.isBusinessException("未找到订单数据");
            }

            // 判断活动是否开启了未满员自动退款,如果开启了,在未满员的情况下,不能核销
            if (NoFullAutoRefundStateEnum.YES.getValue().equals(noFullAutoRefundState)
                    && (enrolledSuccessOrderItems.size() + 1) < tbOrderPo.getTotalStock()) {
                Throw.isBusinessException("报名人数满员才可以确认参与");
            }

            LocalDateTime expireTime = currentOrderItemPo.getExpireTime();
            Integer subOrderState = currentOrderItemPo.getSubOrderState();
            Long orderItemId = currentOrderItemPo.getId();

            // 已核销、已过期，已取消订单,不能确认参与
            // 如果已经确认参与过,不能再次参与
            if (SubOrderStateEnum.VERIFIED.getValue().equals(subOrderState)) {
                Throw.isBusinessException("订单已核销");
            }
            if (SubOrderStateEnum.CANCEL.getValue().equals(subOrderState)) {
                Throw.isBusinessException("订单已取消");
            }
            if (SubOrderStateEnum.EXPIRED.getValue().equals(subOrderState) || !now.isBefore(expireTime)) {
                Throw.isBusinessException("订单已过期");
            }

            if (VerifyTypeEnum.TYF.getValue().equals(currentOrderItemPo.getVerifyType())) {
                Throw.isBusinessException("票付通活动不支持核销");
            }

            // 计算可返金额
//            BigDecimal returnAmt = calReturnAmt(tbOrderPo, activeId, enrolledSuccessOrderItems, orderItemId);

            TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

            try {
                verifyOrderDb(tbOrderPo, now, existNoVerifyOrder, currentOrderItemPo);

                transactionManager.commit(transaction);
            } catch (Exception e) {
                //回滚事务
                transactionManager.rollback(transaction);
                log.error("<用户确认参与报名活动>事务异常回滚", e);
                Throw.isBusinessException(e.getMessage());
            }

            if (OrderStateEnum.VERIFIED.getValue().equals(tbOrderPo.getOrderState())) {
                // 全部核销完再统计
                // 发送mq消息，核销成功，需要异步更新商家与经纪人，商家与商户之间的统计信息
                orderVerifyMsgProvider.sendMsg(orderId);
            }

            return true;
        } finally {
            LockUtils.unlock(lockKey);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void businessOrderAudit(OrderAuditDto orderAuditDto) {
        TbOrderPo orderPo = Optional.ofNullable(baseMapper.selectById(orderAuditDto.getOrderId()))
                .orElseThrow(() -> new BusinessException("订单不存在"));
        Long businessId = orderAuditDto.getBusinessId();
        if (businessId != null && !Objects.equals(orderPo.getBusinessId(), businessId)) {
            Throw.isBusinessException("订单不存在");
        }
        if (!OrderStateEnum.WAIT_AUDIT.getValue().equals(orderPo.getOrderState())) {
            Throw.isBusinessException("订单已非待审核状态");
        }
        if (orderAuditDto.getAuditState() == OrderAuditStateEnum.PASS.getValue()) {
            // 审核通过：待审核 -> 待核销
            orderAuditPass(orderPo);
        } else if (orderAuditDto.getAuditState() == OrderAuditStateEnum.REJECT.getValue()) {
            // 审核拒绝： 待审核 -> 已关闭
            orderAuditReject(orderPo);
        }
    }

    // 审核通过
    private void orderAuditPass(TbOrderPo tbOrderPo) {
        // 审核通过：待审核 -> 待核销
        OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
        orderStateUpdateParam.setId(tbOrderPo.getId());
        orderStateUpdateParam.setUpdateTime(LocalDateTime.now());
        orderStateUpdateParam.setOrgOrderState(tbOrderPo.getOrderState());
        orderStateUpdateParam.setOrderState(OrderStateEnum.WAIT_VERIFY.getValue());
        Integer update = baseMapper.updateOrderState(orderStateUpdateParam);
        if (update == 0) {
            log.error("更新订单状态失败，orderId:{}", tbOrderPo.getId());
            Throw.isBusinessException("更新订单状态失败");
        }
        // 更新子单状态
        orderItemMapper.updateSubOrderStateByOrderId(tbOrderPo.getId(), SubOrderStateEnum.WAIT_VERIFY.getValue());
    }

    // 审核拒绝
    private void orderAuditReject(TbOrderPo tbOrderPo) {
        CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
        BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
        cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
        // 更新订单状态，待审核 -> 关闭
        cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
        cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());
        // 订单备注=商家拒绝
        cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.SEVEN);
        if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
            Throw.isBusinessException("操作失败");
        }
        List<TbOrderRefundPo> tbOrderRefundPos = orderRefundMapper.selectList(new QueryWrapper<TbOrderRefundPo>().eq("del_state", 0)
                .eq("order_id", tbOrderPo.getId()));
        if (!CollectionUtils.isEmpty(tbOrderRefundPos)) {
            // 发送mq异步退款
            orderRefundMsgProvider.sendMsg(tbOrderRefundPos.get(0).getId());
        }
    }

    @Override
    public Page<AdminOrderPageVo> pageAdminOrder(AdminOrderPageDto adminOrderPageDto) {
        String payTimeStart = adminOrderPageDto.getPayTimeStart();
        String payTimeEnd = adminOrderPageDto.getPayTimeEnd();
        String orderTimeStart = adminOrderPageDto.getOrderTimeStart();
        String orderTimeEnd = adminOrderPageDto.getOrderTimeEnd();

        if (!StringUtils.isBlank(payTimeStart)) {
            try {
                LocalDateUtil.toLocalDateTime(payTimeStart, Constant.YYYY_MM_DD_HH_MM_SS);
            } catch (Exception e) {
                Throw.isBusinessException("查询支付开始时间格式错误");
            }
        }

        if (!StringUtils.isBlank(payTimeEnd)) {
            try {
                LocalDateUtil.toLocalDateTime(payTimeEnd, Constant.YYYY_MM_DD_HH_MM_SS);
            } catch (Exception e) {
                Throw.isBusinessException("查询支付结束时间格式错误");
            }
        }

        if (!StringUtils.isBlank(orderTimeStart)) {
            try {
                LocalDateUtil.toLocalDateTime(orderTimeStart, Constant.YYYY_MM_DD_HH_MM_SS);
            } catch (Exception e) {
                Throw.isBusinessException("查询下单开始时间格式错误");
            }
        }

        if (!StringUtils.isBlank(orderTimeEnd)) {
            try {
                LocalDateUtil.toLocalDateTime(orderTimeEnd, Constant.YYYY_MM_DD_HH_MM_SS);
            } catch (Exception e) {
                Throw.isBusinessException("查询下单结束时间格式错误");
            }
        }

        String subOrderNo = adminOrderPageDto.getSubOrderNo();
        // 判断是否是根据子订单号去查询,如果不是,则分页查主订单表,否则根据子订单号查询主订单数据,再根据主订单id查询子订单列表
        if (!StringUtils.isBlank(subOrderNo)) {
            AdminOrderItemVo adminOrderItemVo = orderItemMapper.getOrderItemBySubOrderNo(subOrderNo);
            if (adminOrderItemVo == null) {
                return new Page<>();
            }

            adminOrderPageDto.setOrderNo(adminOrderItemVo.getOrderNo());
        }

        PageHelper.startPage(adminOrderPageDto.getPageNum(), adminOrderPageDto.getPageSize());
        List<AdminOrderPageVo> orderPageVoList = baseMapper.listAdminOrderByDto(adminOrderPageDto);
        if (!CollectionUtils.isEmpty(orderPageVoList)) {
            List<Long> orderIds = orderPageVoList.stream().map(AdminOrderPageVo::getId).collect(Collectors.toList());

            Map<Long, List<AdminOrderItemVo>> adminOrderItemVoMap = new HashMap<>();
            List<AdminOrderItemVo> adminOrderItemVos = orderItemMapper.listAdminOrderItemByOrderIds(orderIds);
            if (!CollectionUtils.isEmpty(adminOrderItemVos)) {
                adminOrderItemVoMap = adminOrderItemVos.stream().collect(Collectors.groupingBy(AdminOrderItemVo::getOrderId));
            }

            for (AdminOrderPageVo adminOrderPageVo : orderPageVoList) {
                Long agentId = adminOrderPageVo.getAgentId();
                // 计算佣金类型(0-无,1-固定佣金,2-专属佣金比例)
                Integer calCommissionType = adminOrderPageVo.getCalCommissionType();
                // 总补贴金额=订单补贴+红包+折扣补贴+分佣金额
                BigDecimal totalSubsidyAmt = BigDecimal.ZERO;
                // 总返还金额
                BigDecimal totalReturnAmt = BigDecimal.ZERO;
                // 推广权益类型:0-无,1-其他权益,2-佣金
                int promotionEquityType = 0;

//                BigDecimal redPacketAmt = adminOrderPageVo.getRedPacketAmt();
//                if (redPacketAmt != null && redPacketAmt.compareTo(BigDecimal.ZERO) > 0) {
//                    totalSubsidyAmt = totalSubsidyAmt.add(redPacketAmt);
//                }

                List<AdminOrderItemVo> adminOrderItemVoList = adminOrderItemVoMap.get(adminOrderPageVo.getId());
                Boolean isPft = false;
                if (!CollectionUtils.isEmpty(adminOrderItemVoList)) {
                    for (AdminOrderItemVo adminOrderItemVo : adminOrderItemVoList) {
                        // 订单补贴
//                        BigDecimal merchantSubsidyAmt = adminOrderItemVo.getMerchantSubsidyAmt();
//                        if (merchantSubsidyAmt != null && merchantSubsidyAmt.compareTo(BigDecimal.ZERO) > 0) {
//                            totalSubsidyAmt = totalSubsidyAmt.add(merchantSubsidyAmt);
//                        }
                        if (adminOrderItemVo.getEnrollInfo() != null) {
                            adminOrderItemVo.setGoodsName("【活动签到】" + adminOrderItemVo.getGoodsName());
                        }

                        // 总补贴
                        BigDecimal totalSubsidy = adminOrderItemVo.getTotalSubsidyAmt();
                        if (totalSubsidy != null && totalSubsidy.compareTo(BigDecimal.ZERO) > 0) {
                            totalSubsidyAmt = totalSubsidyAmt.add(totalSubsidy);
                        }

                        // 退返金额
                        BigDecimal returnAmt = adminOrderItemVo.getReturnAmt();
                        if (returnAmt != null && returnAmt.compareTo(BigDecimal.ZERO) > 0) {
                            totalReturnAmt = totalReturnAmt.add(returnAmt);
                        }
                        if (VerifyTypeEnum.TYF.getValue().equals(adminOrderItemVo.getVerifyType())) {
                            isPft = true;
                        }
                    }
                }

                if (agentId != null && agentId > 0) {
//                    promotionEquityType = CalCommissionTypeEnum.NO.getValue().equals(calCommissionType) ? 1 : 2;
                    promotionEquityType = 2;
                }

                BigDecimal totalCommissionAmt = adminOrderPageVo.getActualCommissionAmt();
                BigDecimal agent1CommissionAmt = totalCommissionAmt;
                BigDecimal agent2CommissionAmt = adminOrderPageVo.getSubAgentCommissionAmt();
                if (agent2CommissionAmt.compareTo(BigDecimal.ZERO) > 0) {
                    agent1CommissionAmt = agent1CommissionAmt.subtract(agent2CommissionAmt);
                }
                adminOrderPageVo.setPromotionEquityType(promotionEquityType);
                adminOrderPageVo.setTotalCommissionAmt(totalCommissionAmt);
                adminOrderPageVo.setAgent1CommissionAmt(agent1CommissionAmt);
                adminOrderPageVo.setAgent2CommissionAmt(agent2CommissionAmt);
                adminOrderPageVo.setTotalSubsidyAmt(totalSubsidyAmt);
                adminOrderPageVo.setTotalReturnAmt(totalReturnAmt);
                adminOrderPageVo.setAdminOrderItems(adminOrderItemVoList);
                adminOrderPageVo.setIsPft(isPft);
            }
        }

        PageInfo<AdminOrderPageVo> pageInfo = new PageInfo<>(orderPageVoList);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    @Override
    public Page<AdminPointsOrderPageVo> pageAdminPointsOrder(AdminPointsOrderPageDto adminPointsOrderPageDto) {
        String orderTimeStart = adminPointsOrderPageDto.getOrderTimeStart();
        String orderTimeEnd = adminPointsOrderPageDto.getOrderTimeEnd();

        if (!StringUtils.isBlank(orderTimeStart)) {
            try {
                LocalDateUtil.toLocalDateTime(orderTimeStart, Constant.YYYY_MM_DD_HH_MM_SS);
            } catch (Exception e) {
                Throw.isBusinessException("查询下单开始时间格式错误");
            }
        }

        if (!StringUtils.isBlank(orderTimeEnd)) {
            try {
                LocalDateUtil.toLocalDateTime(orderTimeEnd, Constant.YYYY_MM_DD_HH_MM_SS);
            } catch (Exception e) {
                Throw.isBusinessException("查询下单结束时间格式错误");
            }
        }

        List<Integer> orderStates = new ArrayList<>();
        // 处理订单状态
        // 前端显示订单状态(2 - 待核销（包含待核销/核销中）, 3 - 已完成（包含已核销/已完成）, 4 - 已关闭（包含已取消/已关闭）)
        Integer orderState = adminPointsOrderPageDto.getOrderState();
        if (orderState != null) {
            if (FrontOrderStateEnum.WAIT_VERIFY.getValue().equals(orderState)) {
                orderStates.add(OrderStateEnum.WAIT_VERIFY.getValue());
                orderStates.add(OrderStateEnum.VERIFYING.getValue());
            } else if (FrontOrderStateEnum.FINISH.getValue().equals(orderState)) {
                orderStates.add(OrderStateEnum.VERIFIED.getValue());
                orderStates.add(OrderStateEnum.FINISH.getValue());
            } else if (FrontOrderStateEnum.CLOSE.getValue().equals(orderState)) {
                orderStates.add(OrderStateEnum.CANCEL.getValue());
                orderStates.add(OrderStateEnum.CLOSE.getValue());
            }

            adminPointsOrderPageDto.setOrderState(null);
            adminPointsOrderPageDto.setOrderStates(orderStates);
        }

        PageHelper.startPage(adminPointsOrderPageDto.getPageNum(), adminPointsOrderPageDto.getPageSize());
        List<AdminPointsOrderPageVo> orderPageVoList = baseMapper.listAdminPointsOrderByDto(adminPointsOrderPageDto);
        if (!CollectionUtils.isEmpty(orderPageVoList)) {
            List<Long> merchantIds = orderPageVoList.stream().map(AdminPointsOrderPageVo::getMerchantId).collect(Collectors.toList());
            // 查询商户数据
            Map<Long, MerchantDetailVo> merchantMap = new HashMap<>();
            List<MerchantDetailVo> merchantVos = merchantApi.listDetailByIds(merchantIds).unpack();
            if (!CollectionUtils.isEmpty(merchantVos)) {
                merchantMap = merchantVos.stream().collect(Collectors.toMap(MerchantDetailVo::getId, Function.identity(), (k1, k2) -> k1));
            }

            for (AdminPointsOrderPageVo adminPointsOrderPageVo : orderPageVoList) {
                Long merchantId = adminPointsOrderPageVo.getMerchantId();
                if (merchantId == null || merchantId == 0) {
                    continue;
                }

                MerchantDetailVo merchantDetailVo = merchantMap.get(merchantId);
                if (merchantDetailVo == null) {
                    continue;
                }

                adminPointsOrderPageVo.setMerchantName(merchantDetailVo.getMerchantName());
            }
        }

        PageInfo<AdminPointsOrderPageVo> pageInfo = new PageInfo<>(orderPageVoList);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    @Override
    public Page<AdminCommissionOrderPageVo> pageAdminCommissionOrder(AdminCommissionOrderPageDto adminCommissionOrderPageDto) {
        PageHelper.startPage(adminCommissionOrderPageDto.getPageNum(), adminCommissionOrderPageDto.getPageSize());
        List<AdminCommissionOrderPageVo> orderPageVoList = baseMapper.listAdminCommissionOrderByDto(adminCommissionOrderPageDto);
        if (!CollectionUtils.isEmpty(orderPageVoList)) {
            for (AdminCommissionOrderPageVo vo : orderPageVoList) {
                vo.setAgentMobile(PrivacyUtil.encryptMobile(vo.getAgentMobile()));
            }
        }

        PageInfo<AdminCommissionOrderPageVo> pageInfo = new PageInfo<>(orderPageVoList);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    @Override
    public List<AdminCommissionOrderPageVo> listAdminCommissionOrder(AdminCommissionOrderPageDto adminCommissionOrderPageDto) {
        return Optional.ofNullable(baseMapper.listAdminCommissionOrderByDto(adminCommissionOrderPageDto))
                .orElse(Collections.emptyList());
    }

    @Override
    public List<AdminPointsOrderPageVo> listAdminPointsOrder(AdminPointsOrderPageDto adminPointsOrderPageDto) {
        String orderTimeStart = adminPointsOrderPageDto.getOrderTimeStart();
        String orderTimeEnd = adminPointsOrderPageDto.getOrderTimeEnd();

        if (!StringUtils.isBlank(orderTimeStart)) {
            try {
                LocalDateUtil.toLocalDateTime(orderTimeStart, Constant.YYYY_MM_DD_HH_MM_SS);
            } catch (Exception e) {
                Throw.isBusinessException("查询下单开始时间格式错误");
            }
        }

        if (!StringUtils.isBlank(orderTimeEnd)) {
            try {
                LocalDateUtil.toLocalDateTime(orderTimeEnd, Constant.YYYY_MM_DD_HH_MM_SS);
            } catch (Exception e) {
                Throw.isBusinessException("查询下单结束时间格式错误");
            }
        }

        List<Integer> orderStates = new ArrayList<>();
        // 处理订单状态
        // 前端显示订单状态(2 - 待核销（包含待核销/核销中）, 3 - 已完成（包含已核销/已完成）, 4 - 已关闭（包含已取消/已关闭）)
        Integer orderState = adminPointsOrderPageDto.getOrderState();
        if (orderState != null) {
            if (FrontOrderStateEnum.WAIT_VERIFY.getValue().equals(orderState)) {
                orderStates.add(OrderStateEnum.WAIT_VERIFY.getValue());
                orderStates.add(OrderStateEnum.VERIFYING.getValue());
            } else if (FrontOrderStateEnum.FINISH.getValue().equals(orderState)) {
                orderStates.add(OrderStateEnum.VERIFIED.getValue());
                orderStates.add(OrderStateEnum.FINISH.getValue());
            } else if (FrontOrderStateEnum.CLOSE.getValue().equals(orderState)) {
                orderStates.add(OrderStateEnum.CANCEL.getValue());
                orderStates.add(OrderStateEnum.CLOSE.getValue());
            }

            adminPointsOrderPageDto.setOrderState(null);
            adminPointsOrderPageDto.setOrderStates(orderStates);
        }

        List<AdminPointsOrderPageVo> orderPageVoList = baseMapper.listAdminPointsOrderByDto(adminPointsOrderPageDto);
        if (!CollectionUtils.isEmpty(orderPageVoList)) {
            List<Long> merchantIds = orderPageVoList.stream().map(AdminPointsOrderPageVo::getMerchantId).collect(Collectors.toList());
            // 查询商户数据
            Map<Long, MerchantDetailVo> merchantMap = new HashMap<>();
            List<MerchantDetailVo> merchantVos = merchantApi.listDetailByIds(merchantIds).unpack();
            if (!CollectionUtils.isEmpty(merchantVos)) {
                merchantMap = merchantVos.stream().collect(Collectors.toMap(MerchantDetailVo::getId, Function.identity(), (k1, k2) -> k1));
            }

            List<Long> orderIds = orderPageVoList.stream().map(AdminPointsOrderPageVo::getId).collect(Collectors.toList());

            Map<Long, List<AdminOrderItemVo>> adminOrderItemVoMap = new HashMap<>();
            List<AdminOrderItemVo> adminOrderItemVos = orderItemMapper.listAdminOrderItemByOrderIds(orderIds);
            if (!CollectionUtils.isEmpty(adminOrderItemVos)) {
                adminOrderItemVoMap = adminOrderItemVos.stream().collect(Collectors.groupingBy(AdminOrderItemVo::getOrderId));
            }

            for (AdminPointsOrderPageVo adminPointsOrderPageVo : orderPageVoList) {
                List<AdminOrderItemVo> adminOrderItemVoList = adminOrderItemVoMap.get(adminPointsOrderPageVo.getId());
                adminPointsOrderPageVo.setAdminOrderItems(adminOrderItemVoList);

                Long merchantId = adminPointsOrderPageVo.getMerchantId();
                if (merchantId == null || merchantId == 0) {
                    continue;
                }

                MerchantDetailVo merchantDetailVo = merchantMap.get(merchantId);
                if (merchantDetailVo == null) {
                    continue;
                }

                adminPointsOrderPageVo.setMerchantName(merchantDetailVo.getMerchantName());
            }
        }

        return orderPageVoList;
    }

    @Override
    public List<AdminOrderPageVo> listAdminOrder(AdminOrderPageDto adminOrderPageDto) {
        String payTimeStart = adminOrderPageDto.getPayTimeStart();
        String payTimeEnd = adminOrderPageDto.getPayTimeEnd();
        String orderTimeStart = adminOrderPageDto.getOrderTimeStart();
        String orderTimeEnd = adminOrderPageDto.getOrderTimeEnd();

        if (!StringUtils.isBlank(payTimeStart)) {
            try {
                LocalDateUtil.toLocalDateTime(payTimeStart, Constant.YYYY_MM_DD_HH_MM_SS);
            } catch (Exception e) {
                Throw.isBusinessException("查询支付开始时间格式错误");
            }
        }

        if (!StringUtils.isBlank(payTimeEnd)) {
            try {
                LocalDateUtil.toLocalDateTime(payTimeEnd, Constant.YYYY_MM_DD_HH_MM_SS);
            } catch (Exception e) {
                Throw.isBusinessException("查询支付结束时间格式错误");
            }
        }

        if (!StringUtils.isBlank(orderTimeStart)) {
            try {
                LocalDateUtil.toLocalDateTime(orderTimeStart, Constant.YYYY_MM_DD_HH_MM_SS);
            } catch (Exception e) {
                Throw.isBusinessException("查询下单开始时间格式错误");
            }
        }

        if (!StringUtils.isBlank(orderTimeEnd)) {
            try {
                LocalDateUtil.toLocalDateTime(orderTimeEnd, Constant.YYYY_MM_DD_HH_MM_SS);
            } catch (Exception e) {
                Throw.isBusinessException("查询下单结束时间格式错误");
            }
        }

        String subOrderNo = adminOrderPageDto.getSubOrderNo();
        // 判断是否是根据子订单号去查询,如果不是,则分页查主订单表,否则根据子订单号查询主订单数据,再根据主订单id查询子订单列表
        if (!StringUtils.isBlank(subOrderNo)) {
            AdminOrderItemVo adminOrderItemVo = orderItemMapper.getOrderItemBySubOrderNo(subOrderNo);
            if (adminOrderItemVo == null) {
                return new ArrayList<>();
            }

            adminOrderPageDto.setOrderNo(adminOrderItemVo.getOrderNo());
        }

        List<AdminOrderPageVo> orderPageVoList = baseMapper.listAdminOrderByDto(adminOrderPageDto);
        if (!CollectionUtils.isEmpty(orderPageVoList)) {
            List<Long> orderIds = orderPageVoList.stream().map(AdminOrderPageVo::getId).collect(Collectors.toList());

            Map<Long, List<AdminOrderItemVo>> adminOrderItemVoMap = new HashMap<>();
            List<AdminOrderItemVo> adminOrderItemVos = orderItemMapper.listAdminOrderItemByOrderIds(orderIds);
            if (!CollectionUtils.isEmpty(adminOrderItemVos)) {
                adminOrderItemVoMap = adminOrderItemVos.stream().collect(Collectors.groupingBy(AdminOrderItemVo::getOrderId));
            }

            for (AdminOrderPageVo adminOrderPageVo : orderPageVoList) {
                Long agentId = adminOrderPageVo.getAgentId();
                // 计算佣金类型(0-无,1-固定佣金,2-专属佣金比例)
                Integer calCommissionType = adminOrderPageVo.getCalCommissionType();
                // 总补贴金额=订单补贴+红包+折扣补贴+分佣金额
                BigDecimal totalSubsidyAmt = BigDecimal.ZERO;
                // 总返还金额
                BigDecimal totalReturnAmt = BigDecimal.ZERO;
                // 总实际金额
                BigDecimal totalCommissionAmt = BigDecimal.ZERO;
                // 推广权益类型:0-无,1-其他权益,2-佣金
                int promotionEquityType = 0;

//                BigDecimal redPacketAmt = adminOrderPageVo.getRedPacketAmt();
//                if (redPacketAmt != null && redPacketAmt.compareTo(BigDecimal.ZERO) > 0) {
//                    totalSubsidyAmt = totalSubsidyAmt.add(redPacketAmt);
//                }

                List<AdminOrderItemVo> adminOrderItemVoList = adminOrderItemVoMap.get(adminOrderPageVo.getId());
                Boolean isPft = false;
                if (!CollectionUtils.isEmpty(adminOrderItemVoList)) {
                    for (AdminOrderItemVo adminOrderItemVo : adminOrderItemVoList) {
                        // 订单补贴
//                        BigDecimal merchantSubsidyAmt = adminOrderItemVo.getMerchantSubsidyAmt();
//                        if (merchantSubsidyAmt != null && merchantSubsidyAmt.compareTo(BigDecimal.ZERO) > 0) {
//                            totalSubsidyAmt = totalSubsidyAmt.add(merchantSubsidyAmt);
//                        }

                        // 分佣金额
                        BigDecimal commissionAmt = adminOrderItemVo.getCommissionAmt();
                        if (commissionAmt != null && commissionAmt.compareTo(BigDecimal.ZERO) > 0) {
                            totalCommissionAmt = totalCommissionAmt.add(commissionAmt);

                            // 如果是非报名订单，则总补贴需要加上佣金
//                            if (!ActiveTypeEnum.ENROLL.getValue().equals(adminOrderItemVo.getOrderType())) {
//                                totalSubsidyAmt = totalSubsidyAmt.add(commissionAmt);
//                            }
                        }

                        // 总补贴
                        BigDecimal totalSubsidy = adminOrderItemVo.getTotalSubsidyAmt();
                        if (totalSubsidy != null && totalSubsidy.compareTo(BigDecimal.ZERO) > 0) {
                            totalSubsidyAmt = totalSubsidyAmt.add(totalSubsidy);
                        }

                        // 退返金额
                        BigDecimal returnAmt = adminOrderItemVo.getReturnAmt();
                        if (returnAmt != null && returnAmt.compareTo(BigDecimal.ZERO) > 0) {
                            totalReturnAmt = totalReturnAmt.add(returnAmt);
                        }
                        if (VerifyTypeEnum.TYF.getValue().equals(adminOrderItemVo.getVerifyType())) {
                            isPft = true;
                        }
                    }
                }

                if (agentId != null && agentId > 0) {
                    promotionEquityType = CalCommissionTypeEnum.NO.getValue().equals(calCommissionType) ? 1 : 2;
                }

                adminOrderPageVo.setPromotionEquityType(promotionEquityType);
                adminOrderPageVo.setTotalCommissionAmt(totalCommissionAmt);
                adminOrderPageVo.setTotalSubsidyAmt(totalSubsidyAmt);
                adminOrderPageVo.setTotalReturnAmt(totalReturnAmt);
                adminOrderPageVo.setAdminOrderItems(adminOrderItemVoList);
                adminOrderPageVo.setIsPft(isPft);
            }
        }

        return orderPageVoList;
    }

    @Override
    public List<String> getLastAvatar(Integer count) {
        return baseMapper.getLastAvatar(count);
    }

    @Override
    public AdminGroupOrderDetailVo detailAdminGroupOrder(Long orderId) {
        // 查询订单数据
        AdminGroupOrderDetailVo adminGroupOrderDetailVo = baseMapper.detailAdminGroupOrder(orderId, ActiveTypeEnum.GROUP.getValue());
        if (adminGroupOrderDetailVo == null) {
            Throw.isBusinessException("未找到订单数据");
        }

        Long agentId = adminGroupOrderDetailVo.getAgentId();
        // 计算佣金类型(0-无,1-固定佣金,2-专属佣金比例)
        Integer calCommissionType = adminGroupOrderDetailVo.getCalCommissionType();
        // 总补贴金额=订单补贴+红包+折扣补贴+分佣金额
        BigDecimal totalSubsidyAmt = BigDecimal.ZERO;
        // 总返还金额
        BigDecimal totalReturnAmt = BigDecimal.ZERO;
        // 合计分账本金
        BigDecimal totalMerchantAmt = BigDecimal.ZERO;
        // 合计分账补贴=订单补贴+折扣补贴+红包
        BigDecimal totalMerchantSubsidyAmt = BigDecimal.ZERO;
        // 推广权益类型:0-无,1-其他权益,2-佣金
        int promotionEquityType = 0;

//        BigDecimal redPacketAmt = adminGroupOrderDetailVo.getRedPacketAmt();
//        if (redPacketAmt != null && redPacketAmt.compareTo(BigDecimal.ZERO) > 0) {
//            totalSubsidyAmt = totalSubsidyAmt.add(redPacketAmt);
//        }

        // 查询订单项数据
        Boolean isPft = false;
        List<AdminOrderItemVo> adminOrderItemVoList = orderItemMapper.listAdminOrderItemByOrderIds(Collections.singletonList(orderId));
        if (!CollectionUtils.isEmpty(adminOrderItemVoList)) {
            for (AdminOrderItemVo adminOrderItemVo : adminOrderItemVoList) {
                // 订单补贴
//                BigDecimal merchantSubsidyAmt = adminOrderItemVo.getMerchantSubsidyAmt();
//                if (merchantSubsidyAmt != null && merchantSubsidyAmt.compareTo(BigDecimal.ZERO) > 0) {
//                    totalMerchantSubsidyAmt = totalMerchantSubsidyAmt.add(merchantSubsidyAmt);
//                    totalSubsidyAmt = totalSubsidyAmt.add(merchantSubsidyAmt);
//                }

                // 总补贴
                BigDecimal totalSubsidy = adminOrderItemVo.getTotalSubsidyAmt();
                if (totalSubsidy != null && totalSubsidy.compareTo(BigDecimal.ZERO) > 0) {
                    totalSubsidyAmt = totalSubsidyAmt.add(totalSubsidy);
                    totalMerchantSubsidyAmt = totalMerchantSubsidyAmt.add(totalSubsidy);
                }

                // 分销商户金额
                BigDecimal merchantAmt = adminOrderItemVo.getMerchantAmt();
                if (merchantAmt != null && merchantAmt.compareTo(BigDecimal.ZERO) > 0) {
                    totalMerchantAmt = totalMerchantAmt.add(merchantAmt);
                }

                // 退返金额
                BigDecimal returnAmt = adminOrderItemVo.getReturnAmt();
                if (returnAmt != null && returnAmt.compareTo(BigDecimal.ZERO) > 0) {
                    totalReturnAmt = totalReturnAmt.add(returnAmt);
                }

                if (VerifyTypeEnum.TYF.getValue().equals(adminOrderItemVo.getVerifyType())) {
                    isPft = true;
                }
            }
        }

        // 处理推广权益
        if (agentId != null && agentId > 0) {
            promotionEquityType = CalCommissionTypeEnum.NO.getValue().equals(calCommissionType) ? 1 : 2;
        }

        BigDecimal totalCommissionAmt = adminGroupOrderDetailVo.getActualCommissionAmt();
        BigDecimal agent1CommissionAmt = totalCommissionAmt;
        BigDecimal agent2CommissionAmt = adminGroupOrderDetailVo.getSubAgentCommissionAmt();
        if (agent2CommissionAmt.compareTo(BigDecimal.ZERO) > 0) {
            agent1CommissionAmt = agent1CommissionAmt.subtract(agent2CommissionAmt);
        }
        adminGroupOrderDetailVo.setPromotionEquityType(promotionEquityType);
        adminGroupOrderDetailVo.setTotalCommissionAmt(totalCommissionAmt);
        adminGroupOrderDetailVo.setAgent1CommissionAmt(agent1CommissionAmt);
        adminGroupOrderDetailVo.setAgent2CommissionAmt(agent2CommissionAmt);
        adminGroupOrderDetailVo.setTotalSubsidyAmt(totalSubsidyAmt);
        adminGroupOrderDetailVo.setTotalReturnAmt(totalReturnAmt);
        adminGroupOrderDetailVo.setAdminOrderItems(adminOrderItemVoList);
        adminGroupOrderDetailVo.setTotalMerchantAmt(totalMerchantAmt);
        adminGroupOrderDetailVo.setTotalMerchantSubsidyAmt(totalMerchantSubsidyAmt);
        adminGroupOrderDetailVo.setIsPft(isPft);

        return adminGroupOrderDetailVo;
    }

    @Override
    public AdminOrderDetailVo detailAdminOrder(Long orderId) {
        AdminOrderDetailVo adminOrderDetailVo = baseMapper.detailAdminOrder(orderId);
        if (adminOrderDetailVo == null) {
            Throw.isBusinessException("未找到订单数据");
        }
        Long agentId = adminOrderDetailVo.getAgentId();
        // 计算佣金类型(0-无,1-固定佣金,2-专属佣金比例)
        Integer calCommissionType = adminOrderDetailVo.getCalCommissionType();
        // 总补贴金额=订单补贴+红包+折扣补贴+分佣金额
        BigDecimal totalSubsidyAmt = BigDecimal.ZERO;
        // 总返还金额
        BigDecimal totalReturnAmt = BigDecimal.ZERO;
        // 合计分账本金
        BigDecimal totalMerchantAmt = BigDecimal.ZERO;
        // 合计分账补贴=订单补贴+折扣补贴+红包
        BigDecimal totalMerchantSubsidyAmt = BigDecimal.ZERO;
        // 推广权益类型:0-无,1-其他权益,2-佣金
        int promotionEquityType = 0;

//        BigDecimal redPacketAmt = adminGroupOrderDetailVo.getRedPacketAmt();
//        if (redPacketAmt != null && redPacketAmt.compareTo(BigDecimal.ZERO) > 0) {
//            totalSubsidyAmt = totalSubsidyAmt.add(redPacketAmt);
//        }

        // 查询订单项数据
        Boolean isPft = false;
        List<AdminOrderItemVo> adminOrderItemVoList = orderItemMapper.listAdminOrderItemByOrderIds(Collections.singletonList(orderId));
        if (!CollectionUtils.isEmpty(adminOrderItemVoList)) {
            for (AdminOrderItemVo adminOrderItemVo : adminOrderItemVoList) {
                // 总补贴
                BigDecimal totalSubsidy = adminOrderItemVo.getTotalSubsidyAmt();
                if (totalSubsidy != null && totalSubsidy.compareTo(BigDecimal.ZERO) > 0) {
                    totalSubsidyAmt = totalSubsidyAmt.add(totalSubsidy);
                    totalMerchantSubsidyAmt = totalMerchantSubsidyAmt.add(totalSubsidy);
                }

                // 分销商户金额
                BigDecimal merchantAmt = adminOrderItemVo.getMerchantAmt();
                if (merchantAmt != null && merchantAmt.compareTo(BigDecimal.ZERO) > 0) {
                    totalMerchantAmt = totalMerchantAmt.add(merchantAmt);
                }

                // 退返金额
                BigDecimal returnAmt = adminOrderItemVo.getReturnAmt();
                if (returnAmt != null && returnAmt.compareTo(BigDecimal.ZERO) > 0) {
                    totalReturnAmt = totalReturnAmt.add(returnAmt);
                }

                if (VerifyTypeEnum.TYF.getValue().equals(adminOrderItemVo.getVerifyType())) {
                    isPft = true;
                }
            }
        }

        // 处理推广权益
        if (agentId != null && agentId > 0) {
            promotionEquityType = CalCommissionTypeEnum.NO.getValue().equals(calCommissionType) ? 1 : 2;
        }

        BigDecimal totalCommissionAmt = adminOrderDetailVo.getActualCommissionAmt();
        BigDecimal agent1CommissionAmt = totalCommissionAmt;
        BigDecimal agent2CommissionAmt = adminOrderDetailVo.getSubAgentCommissionAmt();
        if (agent2CommissionAmt.compareTo(BigDecimal.ZERO) > 0) {
            agent1CommissionAmt = agent1CommissionAmt.subtract(agent2CommissionAmt);
        }
        adminOrderDetailVo.setPromotionEquityType(promotionEquityType);
        adminOrderDetailVo.setTotalCommissionAmt(totalCommissionAmt);
        adminOrderDetailVo.setAgent1CommissionAmt(agent1CommissionAmt);
        adminOrderDetailVo.setAgent2CommissionAmt(agent2CommissionAmt);
        adminOrderDetailVo.setTotalSubsidyAmt(totalSubsidyAmt);
        adminOrderDetailVo.setTotalReturnAmt(totalReturnAmt);
        adminOrderDetailVo.setAdminOrderItems(adminOrderItemVoList);
        adminOrderDetailVo.setTotalMerchantAmt(totalMerchantAmt);
        adminOrderDetailVo.setTotalMerchantSubsidyAmt(totalMerchantSubsidyAmt);
        adminOrderDetailVo.setIsPft(isPft);
        adminOrderDetailVo.setOrderEnrollInfos(getOrderEnrollInfos(adminOrderItemVoList));
        adminOrderDetailVo.setEnrolledNum(getEnrolledNum(adminOrderDetailVo.getActiveId(), adminOrderDetailVo.getEndTime()));

        // 是否拼团免单
        if (PromotionTypeEnum.GROUP_BUY.name().equals(adminOrderDetailVo.getPromotionType())) {
            TbGroupBuyOrderItemPo groupBuyOrderItem = groupBuyOrderService.getGroupBuyOrderItemByOrderId(adminOrderDetailVo.getId());
            if (groupBuyOrderItem != null && groupBuyOrderItem.getFree() == 1) {
                adminOrderDetailVo.setFree(groupBuyOrderItem.getFree());
            }
        }

        return adminOrderDetailVo;
    }

    @Override
    public AdminEnrollOrderDetailVo detailAdminEnrollOrder(Long orderId) {
        // 查询订单数据
        AdminEnrollOrderDetailVo adminEnrollOrderDetailVo = baseMapper.detailAdminEnrollOrder(orderId, ActiveTypeEnum.ENROLL.getValue());
        if (adminEnrollOrderDetailVo == null) {
            Throw.isBusinessException("未找到订单数据");
        }

        LocalDateTime endTime = adminEnrollOrderDetailVo.getEndTime();
        Long agentId = adminEnrollOrderDetailVo.getAgentId();
        // 计算佣金类型(0-无,1-固定佣金,2-专属佣金比例)
        Integer calCommissionType = adminEnrollOrderDetailVo.getCalCommissionType();
        // 总补贴金额=订单补贴+红包+折扣补贴+分佣金额
        BigDecimal totalSubsidyAmt = BigDecimal.ZERO;
        // 总返还金额
        BigDecimal totalReturnAmt = BigDecimal.ZERO;
        // 合计分账本金
        BigDecimal totalMerchantAmt = BigDecimal.ZERO;
        // 推广权益类型:0-无,1-其他权益,2-佣金
        int promotionEquityType = 0;
        // 合计分账补贴=订单补贴+折扣补贴+红包
        BigDecimal totalMerchantSubsidyAmt = BigDecimal.ZERO;

//        BigDecimal redPacketAmt = adminEnrollOrderDetailVo.getRedPacketAmt();
//        if (redPacketAmt != null && redPacketAmt.compareTo(BigDecimal.ZERO) > 0) {
//            totalSubsidyAmt = totalSubsidyAmt.add(redPacketAmt);
//        }

        // 报名信息
        List<OrderEnrollInfoVo> orderEnrollInfoVos = new ArrayList<>();

        // 查询订单项数据
        List<AdminOrderItemVo> adminOrderItemVoList = orderItemMapper.listAdminOrderItemByOrderIds(Collections.singletonList(orderId));
        if (!CollectionUtils.isEmpty(adminOrderItemVoList)) {
            // 处理报名信息
            orderEnrollInfoVos = getOrderEnrollInfos(adminOrderItemVoList);

            Boolean isPft = false;
            for (AdminOrderItemVo adminOrderItemVo : adminOrderItemVoList) {
                adminOrderItemVo.setEnrollInfo("");
                // 订单补贴
//                BigDecimal merchantSubsidyAmt = adminOrderItemVo.getMerchantSubsidyAmt();
//                if (merchantSubsidyAmt != null && merchantSubsidyAmt.compareTo(BigDecimal.ZERO) > 0) {
//                    totalSubsidyAmt = totalSubsidyAmt.add(merchantSubsidyAmt);
//                }

                // 总补贴
                BigDecimal totalSubsidy = adminOrderItemVo.getTotalSubsidyAmt();
                if (totalSubsidy != null && totalSubsidy.compareTo(BigDecimal.ZERO) > 0) {
                    totalSubsidyAmt = totalSubsidyAmt.add(totalSubsidy);

                    totalMerchantSubsidyAmt = totalMerchantSubsidyAmt.add(totalSubsidy);
                }

                // 分销商户金额
                BigDecimal merchantAmt = adminOrderItemVo.getMerchantAmt();
                if (merchantAmt != null && merchantAmt.compareTo(BigDecimal.ZERO) > 0) {
                    totalMerchantAmt = totalMerchantAmt.add(merchantAmt);
                }

                // 退返金额
                BigDecimal returnAmt = adminOrderItemVo.getReturnAmt();
                if (returnAmt != null && returnAmt.compareTo(BigDecimal.ZERO) > 0) {
                    totalReturnAmt = totalReturnAmt.add(returnAmt);
                }

                if (VerifyTypeEnum.TYF.getValue().equals(adminOrderItemVo.getVerifyType())) {
                    isPft = true;
                }
            }
            adminEnrollOrderDetailVo.setIsPft(isPft);
        }

        // 处理推广权益
        if (agentId != null && agentId > 0) {
            promotionEquityType = CalCommissionTypeEnum.NO.getValue().equals(calCommissionType) ? 1 : 2;
        }

        // 已报名人数
        int enrolledNum = getEnrolledNum(adminEnrollOrderDetailVo.getActiveId(), endTime);

        BigDecimal totalCommissionAmt = adminEnrollOrderDetailVo.getActualCommissionAmt();
        BigDecimal agent1CommissionAmt = totalCommissionAmt;
        BigDecimal agent2CommissionAmt = adminEnrollOrderDetailVo.getSubAgentCommissionAmt();
        if (agent2CommissionAmt.compareTo(BigDecimal.ZERO) > 0) {
            agent1CommissionAmt = agent1CommissionAmt.subtract(agent2CommissionAmt);
        }
        adminEnrollOrderDetailVo.setPromotionEquityType(promotionEquityType);
        adminEnrollOrderDetailVo.setTotalCommissionAmt(totalCommissionAmt);
        adminEnrollOrderDetailVo.setAgent1CommissionAmt(agent1CommissionAmt);
        adminEnrollOrderDetailVo.setAgent2CommissionAmt(agent2CommissionAmt);
        adminEnrollOrderDetailVo.setTotalSubsidyAmt(totalSubsidyAmt);
        adminEnrollOrderDetailVo.setTotalReturnAmt(totalReturnAmt);
        adminEnrollOrderDetailVo.setAdminOrderItems(adminOrderItemVoList);
        adminEnrollOrderDetailVo.setEnrolledNum(enrolledNum);
//        adminEnrollOrderDetailVo.setActiveEnrollInfoSons(activeEnrollInfoSons);
        adminEnrollOrderDetailVo.setOrderEnrollInfos(orderEnrollInfoVos);
        adminEnrollOrderDetailVo.setTotalMerchantAmt(totalMerchantAmt);
        adminEnrollOrderDetailVo.setTotalMerchantSubsidyAmt(totalMerchantSubsidyAmt);
        return adminEnrollOrderDetailVo;
    }

    private int getEnrolledNum(Long activeId, LocalDateTime endTime) {
        int enrolledNum = 0;
        List<TbOrderItemPo> activeEnrollOrderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                .eq("active_id", activeId).isNotNull("enroll_info"));
        if (!CollectionUtils.isEmpty(activeEnrollOrderItemPos)) {
            // 过滤符合报名条件的用户（只要在活动结束前没取消的都算，活动结束后取消也算）
            for (TbOrderItemPo orderItemPo : activeEnrollOrderItemPos) {
                // 如果用户取消参与活动，且活动结束时间不早于取消活动时间，则不计入报名用户数
                if (SubOrderStateEnum.CANCEL.getValue().equals(orderItemPo.getSubOrderState())
                        && endTime.compareTo(orderItemPo.getCancelTime()) >= 0) {
                    continue;
                }

                enrolledNum += 1;
            }
        }
        return enrolledNum;
    }

    private List<OrderEnrollInfoVo> getOrderEnrollInfos(List<AdminOrderItemVo> adminOrderItemVoList) {
        Optional<AdminOrderItemVo> first = adminOrderItemVoList.stream()
                .filter(e -> StringUtils.isNotBlank(e.getEnrollInfo())).findFirst();
        if (!first.isPresent()) {
            return Collections.emptyList();
        }
        List<OrderEnrollInfoVo> orderEnrollInfoVos = new ArrayList<>();
        String enrollInfo = first.get().getEnrollInfo();
        List<ActiveEnrollInfoSonDto> activeEnrollInfoSonDtos = JSON.parseArray(enrollInfo, ActiveEnrollInfoSonDto.class);
        if (!CollectionUtils.isEmpty(activeEnrollInfoSonDtos)) {
            for (ActiveEnrollInfoSonDto activeEnrollInfoSonDto : activeEnrollInfoSonDtos) {
                String title = activeEnrollInfoSonDto.getTitle();
                Integer sort = activeEnrollInfoSonDto.getSort();

                OrderEnrollInfoVo orderEnrollInfoVo = new OrderEnrollInfoVo();
                orderEnrollInfoVo.setTitle(title);
                orderEnrollInfoVo.setSort(sort);

                // 类型(1-填写项，2-单选项，3-多选项)
                Integer type = activeEnrollInfoSonDto.getType();
                if (ActiveEnrollInfoTypeEnum.WRITE.getValue().equals(type)) {
                    // 填写
                    orderEnrollInfoVo.setValue(activeEnrollInfoSonDto.getContent());
                } else if (ActiveEnrollInfoTypeEnum.SINGLE.getValue().equals(type)) {
                    // 单选
                    StringBuilder valueStringBuilder = new StringBuilder();
                    List<ActiveEnrollInfoOptionDto> activeEnrollInfoOptions = activeEnrollInfoSonDto.getActiveEnrollInfoOptions();
                    for (ActiveEnrollInfoOptionDto activeEnrollInfoOption : activeEnrollInfoOptions) {
                        // 勾选状态：1-未勾选，2-已勾选
                        Integer checkState = activeEnrollInfoOption.getCheckState();
                        if (checkState != null && checkState == 2) {
                            String optionText = activeEnrollInfoOption.getOptionText();
                            valueStringBuilder.append(optionText).append("、");
                        }
                    }

                    if (valueStringBuilder.length() > 0) {
                        valueStringBuilder.deleteCharAt(valueStringBuilder.length() - 1);
                        String value = valueStringBuilder.toString();
                        orderEnrollInfoVo.setValue(value);
                    }
                } else if (ActiveEnrollInfoTypeEnum.MULTIPLE.getValue().equals(type)) {
                    // 多选
                    StringBuilder valueStringBuilder = new StringBuilder();
                    List<ActiveEnrollInfoOptionDto> activeEnrollInfoOptions = activeEnrollInfoSonDto.getActiveEnrollInfoOptions();
                    for (ActiveEnrollInfoOptionDto activeEnrollInfoOption : activeEnrollInfoOptions) {
                        // 勾选状态：1-未勾选，2-已勾选
                        Integer checkState = activeEnrollInfoOption.getCheckState();
                        if (checkState != null && checkState == 2) {
                            String optionText = activeEnrollInfoOption.getOptionText();
                            valueStringBuilder.append(optionText).append("、");
                        }
                    }

                    if (valueStringBuilder.length() > 0) {
                        valueStringBuilder.deleteCharAt(valueStringBuilder.length() - 1);
                        String value = valueStringBuilder.toString();
                        orderEnrollInfoVo.setValue(value);
                    }
                }

                orderEnrollInfoVos.add(orderEnrollInfoVo);
            }
        }
        return orderEnrollInfoVos;
    }

    @Override
    public List<AdminOrderCountVo> getOrderCount(AdminOrderCountDto adminOrderCountDto) {
        Map<Integer, AdminOrderCountVo> adminOrderCountVoMap = new HashMap<>();
        List<AdminOrderCountVo> orderCounts = baseMapper.getOrderCount(adminOrderCountDto);
        if (!CollectionUtils.isEmpty(orderCounts)) {
            adminOrderCountVoMap = orderCounts.stream()
                    .collect(Collectors.toMap(AdminOrderCountVo::getOrderState, Function.identity(), (k1, k2) -> k2));
        }

        int totalNum = 0;
        List<AdminOrderCountVo> adminOrderCountVos = new ArrayList<>();
        for (OrderStateEnum value : OrderStateEnum.values()) {
            AdminOrderCountVo adminOrderCountVo = adminOrderCountVoMap.get(value.getValue());
            if (adminOrderCountVo == null) {
                adminOrderCountVo = new AdminOrderCountVo();
                adminOrderCountVo.setOrderState(value.getValue());
                adminOrderCountVo.setNum(0);
            }

            totalNum += adminOrderCountVo.getNum();
            adminOrderCountVos.add(adminOrderCountVo);
        }

        AdminOrderCountVo adminOrderCountVo = new AdminOrderCountVo();
        adminOrderCountVo.setOrderState(0);
        adminOrderCountVo.setNum(totalNum);
        adminOrderCountVos.add(adminOrderCountVo);

        return adminOrderCountVos;
    }

    @Override
    public Page<MerchantOrderPageVo> pageMerchantOrder(MerchantOrderPageDto merchantOrderPageDto) {
//        Integer orderType = merchantOrderPageDto.getOrderType();
//        if (orderType == null || ActiveTypeEnum.typeOf(orderType) == null) {
//            Throw.isBusinessException("请选择订单类型");
//        }
        // selectKey增加手机号，先用正则匹配是否手机号，然后根据手机号获取userId
        if (RegexUtil.isMobileSimple(merchantOrderPageDto.getSelectKey())) {
            merchantOrderPageDto.setSelectKey("");
            AppUserVo appUser = appUserApi.getByMobile(merchantOrderPageDto.getSelectKey()).unpack();
            if (appUser != null) {
                merchantOrderPageDto.setMobile(appUser.getMobile());
            }
        }

        PageHelper.startPage(merchantOrderPageDto.getPageNum(), merchantOrderPageDto.getPageSize());
        List<MerchantOrderPageVo> orderPageVoList = orderItemMapper.listMerchantOrderByDto(merchantOrderPageDto);

        // 调用appUserApi查询用户信息，回填用户信息字段
        List<Long> userIds = orderPageVoList.stream().map(MerchantOrderPageVo::getUserId).collect(Collectors.toList());
        Map<Long, AppUserVo> userMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(userIds)) {
            List<AppUserVo> userList = appUserApi.listByUserIds(userIds).unpack();
            if (!CollectionUtils.isEmpty(userList)) {
                userMap = userList.stream().collect(Collectors.toMap(AppUserVo::getId, Function.identity()));
            }
        }
        for (MerchantOrderPageVo merchantOrderPageVo : orderPageVoList) {
            AppUserVo appUserVo = userMap.get(merchantOrderPageVo.getUserId());
            if (appUserVo != null) {
                merchantOrderPageVo.setUserMobile(PrivacyUtil.encryptMobile(appUserVo.getMobile()));
                merchantOrderPageVo.setNickname(appUserVo.getNickName());
            }
            // 签到订单，显示签到码
            if (merchantOrderPageVo.getEnrollInfo() != null) {
                merchantOrderPageVo.setGoodsName("【活动签到】" + merchantOrderPageVo.getGoodsName());
            }
        }

        PageInfo<MerchantOrderPageVo> pageInfo = new PageInfo<>(orderPageVoList);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    @Override
    public List<MerchantOrderExportVo> exportMerchantOrder(MerchantOrderExportDto merchantOrderExportDto) {
        MerchantOrderPageDto merchantOrderPageDto = BeanUtil.copyProperties(merchantOrderExportDto, MerchantOrderPageDto.class);
        List<MerchantOrderPageVo> orderPageVoList = orderItemMapper.listMerchantOrderByDto(merchantOrderPageDto);
        // 调用appUserApi查询用户信息，回填用户信息字段
        List<Long> userIds = orderPageVoList.stream().map(MerchantOrderPageVo::getUserId).collect(Collectors.toList());
        Map<Long, AppUserVo> userMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(userIds)) {
            List<AppUserVo> userList = appUserApi.listByUserIds(userIds).unpack();
            if (!CollectionUtils.isEmpty(userList)) {
                userMap = userList.stream().collect(Collectors.toMap(AppUserVo::getId, Function.identity()));
            }
        }
        for (MerchantOrderPageVo merchantOrderPageVo : orderPageVoList) {
            AppUserVo appUserVo = userMap.get(merchantOrderPageVo.getUserId());
            if (appUserVo != null) {
                merchantOrderPageVo.setUserMobile(PrivacyUtil.encryptMobile(appUserVo.getMobile()));
                merchantOrderPageVo.setNickname(appUserVo.getNickName());
            }
        }
        return BeanUtils.copyListProperties(orderPageVoList, MerchantOrderExportVo::new);
    }

    @Override
    public MerchantOrderDetailVo detailMerchantOrder(Long orderItemId, Long merchantId) {
        MerchantOrderDetailVo merchantOrderDetailVo = orderItemMapper.detailMerchantOrder(orderItemId, merchantId);
        if (merchantOrderDetailVo == null) {
            Throw.isBusinessException("未找到订单数据");
        }

        BigDecimal totalAmt = BigDecimal.ZERO;
        Integer orderType = merchantOrderDetailVo.getOrderType();
        if (ActiveTypeEnum.GROUP.getValue().equals(orderType)) {
            // 总计=活动价格
            totalAmt = merchantOrderDetailVo.getGoodsPrice();
        } else if (ActiveTypeEnum.ENROLL.getValue().equals(orderType)
                || OrderItemTypeEnum.SIGN_IN.getValue().equals(merchantOrderDetailVo.getItemType())) {
            // 总计=活动价格-可返金额
            totalAmt = merchantOrderDetailVo.getGoodsPrice().subtract(merchantOrderDetailVo.getReturnAmt());

            merchantOrderDetailVo.setGoodsName("【活动签到】" + merchantOrderDetailVo.getGoodsName());

            String enrollInfo = merchantOrderDetailVo.getEnrollInfo();
            if (!StringUtils.isBlank(enrollInfo)) {
                List<OrderEnrollInfoVo> orderEnrollInfoVos = new ArrayList<>();

                List<ActiveEnrollInfoSonDto> activeEnrollInfoSonDtos = JSON.parseArray(enrollInfo, ActiveEnrollInfoSonDto.class);
                for (ActiveEnrollInfoSonDto activeEnrollInfoSonDto : activeEnrollInfoSonDtos) {
                    String title = activeEnrollInfoSonDto.getTitle();
                    Integer sort = activeEnrollInfoSonDto.getSort();

                    OrderEnrollInfoVo orderEnrollInfoVo = new OrderEnrollInfoVo();
                    orderEnrollInfoVo.setTitle(title);
                    orderEnrollInfoVo.setSort(sort);

                    // 类型(1-填写项，2-单选项，3-多选项)
                    Integer type = activeEnrollInfoSonDto.getType();
                    if (ActiveEnrollInfoTypeEnum.WRITE.getValue().equals(type)) {
                        // 填写
                        orderEnrollInfoVo.setValue(activeEnrollInfoSonDto.getContent());
                    } else {
                        // 单选
                        StringBuilder valueStringBuilder = new StringBuilder();
                        List<ActiveEnrollInfoOptionDto> activeEnrollInfoOptions = activeEnrollInfoSonDto.getActiveEnrollInfoOptions();
                        for (ActiveEnrollInfoOptionDto activeEnrollInfoOption : activeEnrollInfoOptions) {
                            // 勾选状态：1-未勾选，2-已勾选
                            Integer checkState = activeEnrollInfoOption.getCheckState();
                            if (checkState != null && checkState == 2) {
                                String optionText = activeEnrollInfoOption.getOptionText();
                                valueStringBuilder.append(optionText).append(",");
                            }
                        }

                        if (valueStringBuilder.length() > 0) {
                            valueStringBuilder.deleteCharAt(valueStringBuilder.length() - 1);
                            String value = valueStringBuilder.toString();
                            orderEnrollInfoVo.setValue(value);
                        }
                    }

                    orderEnrollInfoVos.add(orderEnrollInfoVo);
                }
                merchantOrderDetailVo.setOrderEnrollInfos(orderEnrollInfoVos);
                merchantOrderDetailVo.setEnrollInfo("");
            }
        }
        merchantOrderDetailVo.setTotalAmt(totalAmt);

        // 对下单人手机号脱敏
        merchantOrderDetailVo.setOrderMobile(PrivacyUtil.encryptMobile(merchantOrderDetailVo.getOrderMobile()));
        if (merchantOrderDetailVo.getOrderType().equals(ActiveTypeEnum.POINTS.getValue())) {
            merchantOrderDetailVo.setActiveTitle("积分商场");
        }

        return merchantOrderDetailVo;
    }

    @Override
    public MerchantVerifyConfirmVo getByVerifyCode(String verifyCode, Long merchantId) {
        MerchantVerifyConfirmVo merchantVerifyConfirmVo = orderItemMapper.getByVerifyCode(verifyCode);
        if (merchantVerifyConfirmVo == null) {
            log.error("识别失败，未找到核销数据，verifyCode：{}", verifyCode);
            Throw.isBusinessException("识别失败");
        }

        if (SubOrderStateEnum.VERIFIED.getValue().equals(merchantVerifyConfirmVo.getSubOrderState())) {
            log.error("该码已核销，verifyCode：{}，subOrderState：{}", verifyCode, merchantVerifyConfirmVo.getSubOrderState());
            Throw.isBusinessException("该码已核销");
        }

        if (SubOrderStateEnum.EXPIRED.getValue().equals(merchantVerifyConfirmVo.getSubOrderState())) {
            log.error("该码已失效，verifyCode：{}，subOrderState：{}", verifyCode, merchantVerifyConfirmVo.getSubOrderState());
            Throw.isBusinessException("该码已失效");
        }

        // 判断核销码是否是该商户核销
        Integer mulState = merchantVerifyConfirmVo.getMulState();
        if (MulStateEnum.YES.getValue().equals(mulState)) {
            String goodsId = merchantVerifyConfirmVo.getGoodsId();
			boolean containsMerchantId = Arrays.stream(goodsId.split(","))
				.anyMatch(id -> Long.parseLong(id) == merchantId);

			if (!containsMerchantId) {
				log.error("识别失败，未匹配商户，verifyCode：{}，goodsId：{}，merchantId：{}", verifyCode, goodsId, merchantId);
				Throw.isBusinessException("识别失败");
			}
        } else {
            Long getMerchantId = merchantVerifyConfirmVo.getMerchantId();
            if (!merchantId.equals(getMerchantId)) {
                log.error("识别失败，未匹配商户，verifyCode：{}，merchantId：{}，getMerchantId：{}", verifyCode, merchantId, getMerchantId);
                Throw.isBusinessException("识别失败");
            }
        }
        merchantVerifyConfirmVo.setMerchantId(null);
        merchantVerifyConfirmVo.setMulState(null);
        merchantVerifyConfirmVo.setGoodsId("");

        TbOrderPo tbOrderPo = baseMapper.selectById(merchantVerifyConfirmVo.getOrderId());
        if (tbOrderPo == null) {
            Throw.isBusinessException("未找到订单数据");
        }

        Integer orderState = tbOrderPo.getOrderState();
        Integer orderType = tbOrderPo.getOrderType();
        Integer verifyMethod = tbOrderPo.getVerifyMethod();
        Integer noFullAutoRefundState = tbOrderPo.getNoFullAutoRefundState();
        LocalDateTime endTime = tbOrderPo.getEndTime();
        LocalDateTime validStartTime = tbOrderPo.getValidStartTime();
        LocalDateTime validEndTime = tbOrderPo.getValidEndTime();
        String validStartTimeStr = LocalDateUtil.toLocalDateTimeToString(validStartTime, "MM.dd HH:mm:ss");
        String validEndTimeStr = LocalDateUtil.toLocalDateTimeToString(validEndTime, "MM.dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();

        if (ActiveTypeEnum.ENROLL.getValue().equals(orderType)) {
            // 只能核销线下核销的报名活动订单
            if (!VerifyMethodEnum.OFF_LINE.getValue().equals(verifyMethod)) {
                Throw.isBusinessException("不能核销线上核销的报名订单");
            }

            // 报名活动开启未满员自动退，活动未结束不可核销
            if (NoFullAutoRefundStateEnum.YES.getValue().equals(noFullAutoRefundState)) {
                if (!now.isAfter(endTime)) {
                    Throw.isBusinessException("请于" + LocalDateUtil.toLocalDateTimeToString(validStartTime, Constant.YYYY_MM_DD_HH_MM_SS) + "后核销");
                }
            }
        }

        if (now.isBefore(validStartTime)) {
            Throw.isBusinessException("请于" + validStartTimeStr + "后核销");
        }

        if (now.isAfter(validEndTime)) {
            Throw.isBusinessException("已过活动核销时间");
        }

        if (OrderStateEnum.WAIT_PAY.getValue().equals(orderState)) {
            log.error("识别失败，订单未支付，verifyCode：{}，merchantId：{}", verifyCode, merchantId);
            Throw.isBusinessException("识别失败");
        }

        // 已取消/已关闭的订单不能确认参与
        if (OrderStateEnum.CANCEL.getValue().equals(orderState) || OrderStateEnum.CLOSE.getValue().equals(orderState)) {
            Throw.isBusinessException("已取消的订单不能核销");
        }

        // 对下单人手机号脱敏
        merchantVerifyConfirmVo.setOrderMobile(PrivacyUtil.encryptMobile(merchantVerifyConfirmVo.getOrderMobile()));

        return merchantVerifyConfirmVo;
    }

    @Override
    public Boolean verify(MerchantVerifyDto merchantVerifyDto) {
        String verifyCode = merchantVerifyDto.getVerifyCode();
        if (StringUtils.isBlank(verifyCode)) {
            Throw.isBusinessException("请选择确认参与的核销码");
        }

        // 对核销码加锁
        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "verify:" + verifyCode);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            Long merchantId = merchantVerifyDto.getMerchantId();
            List<TbOrderItemPo> orderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                    .eq("verify_code", verifyCode));
            if (CollectionUtils.isEmpty(orderItemPos)) {
                log.error("识别失败，未找到订单数据，verifyCode：{}", verifyCode);
                Throw.isBusinessException("识别失败");
            }
            TbOrderItemPo tbOrderItemPo = orderItemPos.get(0);

            if (SubOrderStateEnum.VERIFIED.getValue().equals(tbOrderItemPo.getSubOrderState())) {
                log.error("该码已核销，verifyCode：{}，subOrderState：{}", verifyCode, tbOrderItemPo.getSubOrderState());
                Throw.isBusinessException("该码已核销");
            }

            if (SubOrderStateEnum.EXPIRED.getValue().equals(tbOrderItemPo.getSubOrderState())) {
                log.error("该码已失效，verifyCode：{}，subOrderState：{}", verifyCode, tbOrderItemPo.getSubOrderState());
                Throw.isBusinessException("该码已失效");
            }

            if (VerifyTypeEnum.TYF.getValue().equals(tbOrderItemPo.getVerifyType())) {
                Throw.isBusinessException("票付通活动不支持核销");
            }

            // 判断核销码是否是该商户核销
            Integer mulState = tbOrderItemPo.getMulState();
            if (MulStateEnum.YES.getValue().equals(mulState)) {
                String goodsId = tbOrderItemPo.getGoodsId();
				boolean containsMerchantId = Arrays.stream(goodsId.split(","))
					.anyMatch(id -> Long.parseLong(id) == merchantId);

				if (!containsMerchantId) {
					log.error("识别失败，未匹配商户，verifyCode：{}，goodsId：{}，merchantId：{}", verifyCode, goodsId, merchantId);
					Throw.isBusinessException("识别失败");
				}
            } else {
                Long getMerchantId = tbOrderItemPo.getMerchantId();
                if (!merchantId.equals(getMerchantId)) {
                    log.error("识别失败，未匹配商户，verifyCode：{}，merchantId：{}，getMerchantId：{}", verifyCode, merchantId, getMerchantId);
                    Throw.isBusinessException("识别失败");
                }
            }
            Long orderItemId = tbOrderItemPo.getId();
            Long orderId = tbOrderItemPo.getOrderId();

            List<TbOrderItemPo> tbOrderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                    .eq("order_id", orderId));
            if (CollectionUtils.isEmpty(tbOrderItemPos)) {
                Throw.isBusinessException("未找到订单数据");
            }

            TbOrderPo tbOrderPo = baseMapper.selectById(orderId);
            if (tbOrderPo == null) {
                Throw.isBusinessException("未找到订单数据");
            }

            LocalDateTime endTime = tbOrderPo.getEndTime();
            Long activeId = tbOrderPo.getActiveId();
            Integer orderState = tbOrderPo.getOrderState();
            // 核销方式(1-线上核销，2-线下核销)
            Integer verifyMethod = tbOrderPo.getVerifyMethod();
            // 订单类型(1-团购订单,2-报名订单,4-团购+报名订单,5积分订单)
            Integer orderType = tbOrderPo.getOrderType();
            Integer noFullAutoRefundState = tbOrderPo.getNoFullAutoRefundState();
            LocalDateTime validStartTime = tbOrderPo.getValidStartTime();
            LocalDateTime validEndTime = tbOrderPo.getValidEndTime();
            String validStartTimeStr = LocalDateUtil.toLocalDateTimeToString(validStartTime, Constant.YYYY_MM_DD_HH_MM_SS);
            String validEndTimeStr = LocalDateUtil.toLocalDateTimeToString(validEndTime, Constant.YYYY_MM_DD_HH_MM_SS);
            LocalDateTime now = LocalDateTime.now();

            if (now.isBefore(validStartTime)) {
                Throw.isBusinessException("请于" + validStartTimeStr + "后核销");
            }

            if (now.isAfter(validEndTime)) {
                Throw.isBusinessException("已过活动核销时间");
            }

            if (OrderStateEnum.WAIT_PAY.getValue().equals(orderState)) {
                log.error("识别失败，订单未支付，verifyCode：{}，merchantId：{}", verifyCode, merchantId);
                Throw.isBusinessException("识别失败");
            }

            // 已取消/已关闭的订单不能确认参与
            if (OrderStateEnum.CANCEL.getValue().equals(orderState) || OrderStateEnum.CLOSE.getValue().equals(orderState)) {
                Throw.isBusinessException("已取消的订单不能核销");
            }

            // 是否存在未核销的订单（过滤排除当前核销的订单项，且是待核销的订单项列表, 为空表示不存在未核销的订单项）
            boolean existNoVerifyOrder = !CollectionUtils.isEmpty(tbOrderItemPos.stream()
                    .filter(orderItemPo -> (!orderItemPo.getVerifyCode().equals(verifyCode)
                            && SubOrderStateEnum.WAIT_VERIFY.getValue().equals(orderItemPo.getSubOrderState())))
                    .collect(Collectors.toList()));

            // 报名成功的用户订单（包含取消时间晚于活动结束时间的取消参与用户）
            List<TbOrderItemPo> enrolledSuccessOrderItems = new ArrayList<>();
            if (ActiveTypeEnum.ENROLL.getValue().equals(orderType)) {
                // 只能核销线下核销的报名活动订单
                if (!VerifyMethodEnum.OFF_LINE.getValue().equals(verifyMethod)) {
                    Throw.isBusinessException("不能核销线上核销的报名订单");
                }

                // 报名活动开启未满员自动退，活动未结束不可核销
                if (NoFullAutoRefundStateEnum.YES.getValue().equals(noFullAutoRefundState)) {
                    if (!now.isAfter(endTime)) {
                        Throw.isBusinessException("请于" + LocalDateUtil.toLocalDateTimeToString(validStartTime, Constant.YYYY_MM_DD_HH_MM_SS) + "后核销");
                    }
                }

                List<TbOrderItemPo> tbOrderItemPosByActiveId = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                        .eq("active_id", activeId));

                for (TbOrderItemPo orderItem : tbOrderItemPosByActiveId) {
                    // 如果用户取消参与活动，且活动结束时间不早于取消活动时间，则不计入报名用户数
                    if (SubOrderStateEnum.CANCEL.getValue().equals(orderItem.getSubOrderState())
                            && endTime.compareTo(orderItem.getCancelTime()) >= 0) {
                        continue;
                    }

                    enrolledSuccessOrderItems.add(orderItem);
                }

                // 判断活动是否开启了未满员自动退款,如果开启了,在未满员的情况下,不能核销
                if (NoFullAutoRefundStateEnum.YES.getValue().equals(tbOrderPo.getNoFullAutoRefundState())
                        && enrolledSuccessOrderItems.size() < tbOrderPo.getTotalStock()) {
                    Throw.isBusinessException("报名人数满员才可以核销");
                }
            }

            if (MulStateEnum.YES.getValue().equals(mulState)) {
                tbOrderItemPo.setMerchantId(merchantId);
            }

            // 计算可返金额
//            BigDecimal returnAmt = calReturnAmt(tbOrderPo, activeId, enrolledSuccessOrderItems, orderItemId);

            TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

            try {
                verifyOrderDb(tbOrderPo, now, existNoVerifyOrder, tbOrderItemPo);

                transactionManager.commit(transaction);
            } catch (Exception e) {
                //回滚事务
                transactionManager.rollback(transaction);
                log.error("<商户核销订单>事务异常回滚", e);
                Throw.isBusinessException(e.getMessage());
            }

            if (OrderStateEnum.VERIFIED.getValue().equals(tbOrderPo.getOrderState())) {
                // 全部核销完再统计
                // 发送mq消息，核销成功，需要异步更新商家与经纪人，商家与商户之间的统计信息
                orderVerifyMsgProvider.sendMsg(orderId);
            }

            return true;
        } finally {
            LockUtils.unlock(lockKey);
        }
    }

    private void triggerCashbackTask(Long orderItemId) {
        CompletableFuture.runAsync(() -> {
            log.info("applyCashback: orderItemId={}", orderItemId);
            orderStepPriceCashbackService.applyCashbackWhenVerified(orderItemId);
        });
    }

    @Override
    public Boolean pftVerify(PftOrderCallBackParam param) {
        if (!pftService.checkVerifyCode(param.getVerifyCode())) {
            return false;
        }
        // 对核销码加锁
        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "pftVerify:" + param.getOrder16U());
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            TbOrderItemPo tbOrderItemPo = orderItemMapper.selectOne(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                    .eq("pft_order", param.getOrder16U()));
            if (tbOrderItemPo == null) {
                log.error("识别失败，未找到订单数据，pft_order：{}", param.getOrder16U());
                Throw.isBusinessException("识别失败");
            }

            if (SubOrderStateEnum.VERIFIED.getValue().equals(tbOrderItemPo.getSubOrderState())) {
                return true;
            }

            if (SubOrderStateEnum.EXPIRED.getValue().equals(tbOrderItemPo.getSubOrderState())) {
                Throw.isBusinessException("该码已失效");
            }

            Long orderItemId = tbOrderItemPo.getId();
            Long orderId = tbOrderItemPo.getOrderId();
            String verifyCode = tbOrderItemPo.getVerifyCode();

            List<TbOrderItemPo> tbOrderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                    .eq("order_id", orderId));
            if (CollectionUtils.isEmpty(tbOrderItemPos)) {
                Throw.isBusinessException("未找到订单数据");
            }

            TbOrderPo tbOrderPo = baseMapper.selectById(orderId);
            if (tbOrderPo == null) {
                Throw.isBusinessException("未找到订单数据");
            }

            LocalDateTime endTime = tbOrderPo.getEndTime();
            Long activeId = tbOrderPo.getActiveId();
            Integer orderState = tbOrderPo.getOrderState();
            // 订单类型(1-团购订单,2-报名订单,4-团购+报名订单,5积分订单)
            Integer orderType = tbOrderPo.getOrderType();
            Integer noFullAutoRefundState = tbOrderPo.getNoFullAutoRefundState();
            LocalDateTime validStartTime = tbOrderPo.getValidStartTime();
            LocalDateTime validEndTime = tbOrderPo.getValidEndTime();
            String validStartTimeStr = LocalDateUtil.toLocalDateTimeToString(validStartTime, Constant.YYYY_MM_DD_HH_MM_SS);
            String validEndTimeStr = LocalDateUtil.toLocalDateTimeToString(validEndTime, Constant.YYYY_MM_DD_HH_MM_SS);
            LocalDateTime now = LocalDateTime.now();

            if (now.isBefore(validStartTime)) {
                Throw.isBusinessException("请于" + validStartTimeStr + "后核销");
            }

            if (now.isAfter(validEndTime)) {
                Throw.isBusinessException("已过活动核销时间");
            }

            if (OrderStateEnum.WAIT_PAY.getValue().equals(orderState)) {
                log.error("识别失败，订单未支付，pft_order：{}", param.getOrder16U());
                Throw.isBusinessException("识别失败");
            }

            // 已取消/已关闭的订单不能确认参与
            if (OrderStateEnum.CANCEL.getValue().equals(orderState) || OrderStateEnum.CLOSE.getValue().equals(orderState)) {
                Throw.isBusinessException("已取消的订单不能核销");
            }

            // 是否存在未核销的订单（过滤排除当前核销的订单项，且是待核销的订单项列表, 为空表示不存在未核销的订单项）
            boolean existNoVerifyOrder = !CollectionUtils.isEmpty(tbOrderItemPos.stream()
                    .filter(orderItemPo -> (!orderItemPo.getVerifyCode().equals(verifyCode)
                            && SubOrderStateEnum.WAIT_VERIFY.getValue().equals(orderItemPo.getSubOrderState())))
                    .collect(Collectors.toList()));

            // 报名成功的用户订单（包含取消时间晚于活动结束时间的取消参与用户）
            List<TbOrderItemPo> enrolledSuccessOrderItems = new ArrayList<>();
            if (ActiveTypeEnum.ENROLL.getValue().equals(orderType)) {

                // 报名活动开启未满员自动退，活动未结束不可核销
                if (NoFullAutoRefundStateEnum.YES.getValue().equals(noFullAutoRefundState)) {
                    if (!now.isAfter(endTime)) {
                        Throw.isBusinessException("请于" + LocalDateUtil.toLocalDateTimeToString(validStartTime, Constant.YYYY_MM_DD_HH_MM_SS) + "后核销");
                    }
                }

                List<TbOrderItemPo> tbOrderItemPosByActiveId = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                        .eq("active_id", activeId));

                for (TbOrderItemPo orderItem : tbOrderItemPosByActiveId) {
                    // 如果用户取消参与活动，且活动结束时间不早于取消活动时间，则不计入报名用户数
                    if (SubOrderStateEnum.CANCEL.getValue().equals(orderItem.getSubOrderState())
                            && endTime.compareTo(orderItem.getCancelTime()) >= 0) {
                        continue;
                    }

                    enrolledSuccessOrderItems.add(orderItem);
                }

                // 判断活动是否开启了未满员自动退款,如果开启了,在未满员的情况下,不能核销
                if (NoFullAutoRefundStateEnum.YES.getValue().equals(tbOrderPo.getNoFullAutoRefundState())
                        && enrolledSuccessOrderItems.size() < tbOrderPo.getTotalStock()) {
                    Throw.isBusinessException("报名人数满员才可以核销");
                }
            }

            // 计算可返金额
//            BigDecimal returnAmt = calReturnAmt(tbOrderPo, activeId, enrolledSuccessOrderItems, orderItemId);

            TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

            try {
                verifyOrderDb(tbOrderPo, now, existNoVerifyOrder, tbOrderItemPo);

                transactionManager.commit(transaction);
            } catch (Exception e) {
                //回滚事务
                transactionManager.rollback(transaction);
                log.error("<商户核销订单>事务异常回滚", e);
                Throw.isBusinessException(e.getMessage());
            }

            if (OrderStateEnum.VERIFIED.getValue().equals(tbOrderPo.getOrderState())) {
                // 全部核销完再统计
                // 发送mq消息，核销成功，需要异步更新商家与经纪人，商家与商户之间的统计信息
                orderVerifyMsgProvider.sendMsg(orderId);
            }

            return true;
        } finally {
            LockUtils.unlock(lockKey);
        }
    }

    @Override
    public Boolean pftTicket(PftOrderTicketParam param) {
        if (!pftService.checkVerifyCode(param.getVerifyCode())) {
            return false;
        }
        TbOrderItemPo tbOrderItemPo = orderItemMapper.selectOne(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                .eq("pft_order", param.getPftOrder()).eq("sub_order_no", param.getRemoteOrder()));
        if (tbOrderItemPo == null) {
            return false;
        }
        orderItemMapper.updatePftResult(tbOrderItemPo.getId(), param.getPftOrder(), param.getCode());
        return true;
    }

    private void verifyOrderDb(TbOrderPo tbOrderPo, LocalDateTime now, boolean existNoVerifyOrder, TbOrderItemPo orderItemPo) {
//        orderItemPo.setReturnAmt(returnAmt);
        // 更新子订单状态=已核销
        orderItemPo.setSubOrderState(SubOrderStateEnum.VERIFIED.getValue());
        orderItemPo.setVerifyTime(now);
        int update = orderItemMapper.updateById(orderItemPo);
        if (update == 0) {
            log.error("核销失败，更新子订单状态=已核销，subOrderNo：{}", orderItemPo.getSubOrderNo());
            Throw.isBusinessException("核销失败");
        }

        OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
        orderStateUpdateParam.setId(tbOrderPo.getId());
        orderStateUpdateParam.setOrgOrderState(tbOrderPo.getOrderState());

        // 如果订单存在多个未核销的子订单,则更新订单=核销中,否则,更新订单=已核销
        if (!existNoVerifyOrder) {
            orderStateUpdateParam.setOrderState(OrderStateEnum.VERIFIED.getValue());
            orderStateUpdateParam.setVerifyTime(now);
        } else {
            orderStateUpdateParam.setOrderState(OrderStateEnum.VERIFYING.getValue());
            orderStateUpdateParam.setUpdateTime(now);
        }

        // 更新下单用户积分结算状态
        BigDecimal userPointsAmt = tbOrderPo.getUserPointsAmt();
        if (userPointsAmt.compareTo(BigDecimal.ZERO) > 0 && tbOrderPo.getUserPointsSettleState() == 0) {
            tbOrderPo.setUserPointsSettleState(1);
            orderStateUpdateParam.setUserPointsSettleState(1);
        }

        // 更新订单状态，由待核销/核销中-》核销中，待核销/核销中-》已核销
        update = baseMapper.updateOrderState(orderStateUpdateParam);
        if (update == 0) {
            log.error("核销失败，更新订单状态=核销中/已核销，orgOrderState：{}，orderState：{}，subOrderNo：{}",
                    orderStateUpdateParam.getOrgOrderState(),
                    orderStateUpdateParam.getOrderState(),
                    orderItemPo.getSubOrderNo());
            Throw.isBusinessException("核销失败");
        }

        // 触发返现任务
        if (update == 1
                && SubOrderStateEnum.VERIFIED.getValue().equals(orderItemPo.getSubOrderState())) {
            triggerCashbackTask(orderItemPo.getId());
        }
    }

    @Override
    public Page<MerchantVerifyRecordPageVo> pageVerifyRecord(MerchantVerifyRecordPageDto merchantVerifyRecordPageDto) {
        PageHelper.startPage(merchantVerifyRecordPageDto.getPageNum(), merchantVerifyRecordPageDto.getPageSize());
        List<MerchantVerifyRecordPageVo> orderPageVoList = orderItemMapper.listVerifyRecordByDto(merchantVerifyRecordPageDto);

        PageInfo<MerchantVerifyRecordPageVo> pageInfo = new PageInfo<>(orderPageVoList);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    @Override
    public Page<AdminVerifyRecordPageVo> pageAdminVerifyRecord(ActiveVerifyRecordQueryDto activeVerifyRecordQueryDto) {
        PageHelper.startPage(activeVerifyRecordQueryDto.getPageNum(), activeVerifyRecordQueryDto.getPageSize());
        List<AdminVerifyRecordPageVo> orderPageVoList = orderItemMapper.listAdminVerifyRecordByDto(activeVerifyRecordQueryDto);

        PageInfo<AdminVerifyRecordPageVo> pageInfo = new PageInfo<>(orderPageVoList);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    @Override
    public List<AdminVerifyRecordPageVo> listAdminVerifyRecord(ActiveVerifyRecordQueryDto activeVerifyRecordQueryDto) {
        return Optional.ofNullable(orderItemMapper.listAdminVerifyRecordByDto(activeVerifyRecordQueryDto))
                .orElse(Collections.emptyList());
    }

    @Override
    public List<ActiveVerifyMerchantVo> listVerifyMerchant(Long activeId) {
        return Optional.ofNullable(orderItemMapper.listVerifyMerchant(activeId))
                .orElse(Collections.emptyList());
    }

    @Override
    public Page<MerchantVerifyGoodsPageVo> pageVerifyGoods(MerchantVerifyGoodsPageDto merchantVerifyGoodsPageDto) {
        PageHelper.startPage(merchantVerifyGoodsPageDto.getPageNum(), merchantVerifyGoodsPageDto.getPageSize());
        List<MerchantVerifyGoodsPageVo> orderPageVoList = orderItemMapper.listVerifyGoodsByDto(merchantVerifyGoodsPageDto);

        List<Long> activeIds = orderPageVoList.stream().map(MerchantVerifyGoodsPageVo::getActiveId).collect(Collectors.toList());
        ActiveDto activeDto = new ActiveDto();
        activeDto.setActiveIds(activeIds);
        Map<Long, ActivePageVo> activeMap = new HashMap<>();
        List<ActivePageVo> activeList = activeApi.listByDto(activeDto).unpack();
        if (!CollectionUtils.isEmpty(activeList)) {
            activeMap = activeList.stream().collect(Collectors.toMap(ActivePageVo::getId, Function.identity(), (k1, k2) -> k2));
        }
        for (MerchantVerifyGoodsPageVo pageVo : orderPageVoList) {
            Long activeId = pageVo.getActiveId();
            if (activeId == null || activeId == 0) {
                continue;
            }

            ActivePageVo activePageVo = activeMap.get(activeId);
            if (activePageVo == null) {
                continue;
            }

            pageVo.setActiveTitle(activePageVo.getActiveTitle());
        }

        PageInfo<MerchantVerifyGoodsPageVo> pageInfo = new PageInfo<>(orderPageVoList);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    @Override
    public Page<MerchantVerifyGoodsDetailPageVo> pageVerifyGoodsDetail(MerchantVerifyGoodsDetailPageDto merchantVerifyGoodsDetailPageDto) {
        PageHelper.startPage(merchantVerifyGoodsDetailPageDto.getPageNum(), merchantVerifyGoodsDetailPageDto.getPageSize());
        List<MerchantVerifyGoodsDetailPageVo> orderPageVoList = orderItemMapper.listVerifyGoodsDetailByDto(merchantVerifyGoodsDetailPageDto);

        PageInfo<MerchantVerifyGoodsDetailPageVo> pageInfo = new PageInfo<>(orderPageVoList);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    @Override
    public List<OrderVo> listByDto(OrderDto orderDto) {
        return baseMapper.listByDto(orderDto);
    }

    @Override
    public Integer userBusinessOrderCount(Long userId, Long businessId) {
        return baseMapper.selectCount(new QueryWrapper<TbOrderPo>()
                .eq("del_state", 0)
                .eq("user_id", userId)
                .eq("business_id", businessId)
                .in("order_state",
                        OrderStateEnum.WAIT_PAY.getValue(),
                        OrderStateEnum.WAIT_VERIFY.getValue(),
                        OrderStateEnum.VERIFYING.getValue(),
                        OrderStateEnum.FINISH.getValue(),
                        OrderStateEnum.VERIFIED.getValue(),
                        OrderStateEnum.PAYING.getValue()
                )
        );
    }

    @Override
    public Integer userActiveOrderCount(Long userId, Long activeId) {
        List<Object> results = baseMapper.selectObjs(new QueryWrapper<TbOrderPo>()
                .select("SUM(order_num) as total")
                .eq("del_state", 0)
                .eq("active_id", activeId)
                .eq("user_id", userId)
                .in("order_state",
                        OrderStateEnum.WAIT_PAY.getValue(),
                        OrderStateEnum.WAIT_VERIFY.getValue(),
                        OrderStateEnum.VERIFYING.getValue(),
                        OrderStateEnum.FINISH.getValue(),
                        OrderStateEnum.VERIFIED.getValue(),
                        OrderStateEnum.PAYING.getValue()
                )
        );
        return (results.isEmpty() || results.get(0) == null) ? 0 : ((BigDecimal) results.get(0)).intValue(); // 转换为整数
    }

    @Override
    public Boolean consumerOrderDelayMsg(String orderNo) {
        List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                .eq("order_no", orderNo));
        if (CollectionUtils.isEmpty(tbOrderPos)) {
            log.error("消费延时订单失败，未找到订单数据，orderNo：{}", orderNo);
            return false;
        }

        TbOrderPo tbOrderPo = tbOrderPos.get(0);
        if (!OrderStateEnum.WAIT_PAY.getValue().equals(tbOrderPo.getOrderState())) {
            log.error("消费延时订单失败，订单不是待支付状态，orderNo：{}", orderNo);
            return false;
        }

        // 调用hf查单接口，避免临界点出现支付情况，如果查单状态是支付成功，则修改状态为待核销
        HfTradeQuery hfTradeQuery = new HfTradeQuery();
        hfTradeQuery.setOrgReqDate(tbOrderPo.getHfReqDate());
        hfTradeQuery.setOrgReqSeqId(tbOrderPo.getHfReqSeqId());
        JSONObject jsonObject = hfApi.tradeQuery(hfTradeQuery).unpack();
        if (jsonObject == null) {
            log.error("调用hf查单接口异常");
            return false;
        }

        JSONObject dataJSONObject = jsonObject.getJSONObject("data");
        // 交易状态	P：处理中；S：成功；F：失败；I: 初始（初始状态很罕见，请联系汇付技术人员处理）；
        String transStat = dataJSONObject.getString("trans_stat");
        // NOTPAY，订单未支付
        String bankCode = dataJSONObject.getString("bank_code");
        log.info("消费延时订单做查单，订单第三方交易状态：【{}】，orderNo：{}，bankCode：{}", transStat, orderNo, bankCode);
        if ("S".equals(transStat)) {
//            PaySuccessOrderParam paySuccessOrderParam = new PaySuccessOrderParam();
//            paySuccessOrderParam.setId(tbOrderPo.getId());
//            paySuccessOrderParam.setBusinessId(tbOrderPo.getBusinessId());
//            paySuccessOrderParam.setUserId(tbOrderPo.getUserId());
//            paySuccessOrderParam.setOrderTime(tbOrderPo.getOrderTime());
//            // 更新订单状态，待支付--》 待核销
//            paySuccess(paySuccessOrderParam);
            return true;
        }

        if ("P".equals(transStat)) {
            if (!StringUtils.isBlank(bankCode) && "NOTPAY".equals(bankCode)) {
                CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
                BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
                // 更新订单状态，待支付--》已关闭
                cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
                cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                // 订单备注=超时未支付,系统自动关闭
                cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.THREE);
                cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());

                if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
                    Throw.isBusinessException("取消支付失败");
                }
            }
            return true;
        }

        if ("F".equals(transStat)) {
            CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
            BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
            // 更新订单状态，待支付--》已关闭
            cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
            cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
            // 订单备注=超时未支付,系统自动关闭
            cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.THREE);
            cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());

            if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
                log.error("取消订单失败，orderNo：{}", orderNo);
            }

            return true;
        }

        CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
        BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
        // 更新订单状态，待支付--》已关闭
        cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
        cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
        // 订单备注=超时未支付,系统自动关闭
        cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.THREE);
        cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());

        if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
            Throw.isBusinessException("取消支付失败");
        }

        return true;
    }

    @Override
    public Boolean consumerOrderRefundMsg(Long orderRefundId) {
        TbOrderRefundPo tbOrderRefundPo = orderRefundMapper.selectById(orderRefundId);
        if (tbOrderRefundPo == null || tbOrderRefundPo.getDelState() != 0) {
            log.error("订单退款失败，未找到订单退款记录数据，orderRefundId：{}", orderRefundId);
            return false;
        }

        // 退款交易状态(1-待处理，2-处理中，3-成功，4-失败)
        Integer refundState = tbOrderRefundPo.getRefundState();
        if (!OrderRefundStateEnum.WAIT.getValue().equals(refundState)) {
            log.error("订单退款失败，订单退款已处理，orderRefundId：{}", orderRefundId);
            return false;
        }

        BigDecimal refundAmt = tbOrderRefundPo.getRefundAmt();
        if (refundAmt.compareTo(BigDecimal.ZERO) > 0) {
            // 调用hf退款接口申请退款
            HfTradeRefund hfTradeRefund = new HfTradeRefund();
            hfTradeRefund.setOrgReqDate(tbOrderRefundPo.getOrgReqDate());
            hfTradeRefund.setOrgReqSeqId(tbOrderRefundPo.getOrgReqSeqId());
            hfTradeRefund.setRefundAmt(tbOrderRefundPo.getRefundAmt());
            JSONObject jsonObject = hfApi.tradeRefund(hfTradeRefund).unpack();
            if (jsonObject == null) {
                log.error("订单退款失败，调用hf退款接口失败，orderRefundId：{}", orderRefundId);
                return false;
            }

            JSONObject dataJSONObject = jsonObject.getJSONObject("data");
            // 交易状态	P：处理中、S：成功、F：失败；
            String transStat = dataJSONObject.getString("trans_stat");
            if ("P".equals(transStat)) {
                tbOrderRefundPo.setRefundState(OrderRefundStateEnum.PROCESSING.getValue());
            } else if ("S".equals(transStat)) {
                tbOrderRefundPo.setRefundState(OrderRefundStateEnum.SUCCESS.getValue());
                tbOrderRefundPo.setRefundFinishTime(LocalDateTime.now());

                List<TbOrderItemPo> tbOrderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                        .eq("order_id", tbOrderRefundPo.getOrderId()));
                for (TbOrderItemPo tbOrderItemPo : tbOrderItemPos) {
                    if (!VerifyTypeEnum.TYF.getValue().equals(tbOrderItemPo.getVerifyType()) || StrUtil.isNotBlank(tbOrderItemPo.getPftOrder())) {
                        continue;
                    }
                    boolean flag = pftService.OrderChangePro(tbOrderItemPo.getPftOrder());
                    if (!flag) {
                        log.error("订单项【" + tbOrderItemPo.getSubOrderNo() + "】票付通订单取消失败");
                    }
                }
            } else if ("F".equals(transStat)) {
                tbOrderRefundPo.setRefundState(OrderRefundStateEnum.FAIL.getValue());
                tbOrderRefundPo.setRefundReason(JSON.toJSONString(dataJSONObject));
            }
        } else {
            tbOrderRefundPo.setRefundState(OrderRefundStateEnum.SUCCESS.getValue());
            tbOrderRefundPo.setRefundFinishTime(LocalDateTime.now());
        }

        tbOrderRefundPo.setUpdateTime(LocalDateTime.now());
        orderRefundMapper.updateById(tbOrderRefundPo);

        if (refundAmt.compareTo(BigDecimal.ZERO) > 0 && OrderRefundStateEnum.SUCCESS.getValue().equals(tbOrderRefundPo.getRefundState())) {
            // 发送微信公众号模板消息
            sendWxPubTemplateMsg(tbOrderRefundPo);
        }

        return true;
    }

    private void sendWxPubTemplateMsg(TbOrderRefundPo tbOrderRefundPo) {
        Long orderId = tbOrderRefundPo.getOrderId();
        SendOrderVo sendOrderVo = baseMapper.getSendOrderById(orderId);
        if (sendOrderVo == null) {
            log.error("发送微信公众号模板消息失败，未找到订单数据，orderId：{}", orderId);
            return;
        }

        String openid = sendOrderVo.getOpenid();
        if (StringUtils.isBlank(openid)) {
            log.error("发送微信公众号模板消息失败，用户未关注公众号，orderId：{}，openid：{}", orderId, openid);
            return;
        }

        String refundAmtStr = tbOrderRefundPo.getRefundAmt().toString();
        // 退款类型(1-用户申请退款，2-核销过期自动退,3-报名活动未满员自动退，4-阶梯价格退还，5-票付通出票失败退款)
        Integer refundType = tbOrderRefundPo.getRefundType();

        Boolean sendState = false;
        String wxMsgTemplateTypeName = "";
        if (RefundTypeEnum.USER_REFUND.getValue().equals(refundType) || RefundTypeEnum.PFT_REFUND.getValue().equals(refundType)) {
            // 发送 取消订单 模板消息
            WxMsgTemplateTypeEnum wxMsgTemplateTypeEnum = WxMsgTemplateTypeEnum.ORDER_CANCEL_MSG;
            wxMsgTemplateTypeName = wxMsgTemplateTypeEnum.getName();

            String dataStr = String.format(Constant.WX_PUB_REFUND_NOTICE_JSON, refundAmtStr,
                    sendOrderVo.getOrderNo(), sendOrderVo.getActiveTitle(), wxMsgTemplateTypeEnum.getName());
            sendState = wxPubConfig.sendTemplateMsg(openid, wxMsgTemplateTypeEnum, dataStr);
        } else if (RefundTypeEnum.VERIFY_EXPIRE.getValue().equals(refundType)) {
            // 发送 订单到期未核销，自动退款 模板消息
            WxMsgTemplateTypeEnum wxMsgTemplateTypeEnum = WxMsgTemplateTypeEnum.ORDER_EXPIRE_MSG;
            wxMsgTemplateTypeName = wxMsgTemplateTypeEnum.getName();

            String dataStr = String.format(Constant.WX_PUB_REFUND_NOTICE_JSON, refundAmtStr,
                    sendOrderVo.getOrderNo(), sendOrderVo.getActiveTitle(), wxMsgTemplateTypeEnum.getName());
            sendState = wxPubConfig.sendTemplateMsg(openid, wxMsgTemplateTypeEnum, dataStr);
        } else if (RefundTypeEnum.NO_FULL.getValue().equals(refundType)) {
            // 发送 报名活动未满员，自动关闭订单 模板消息
            WxMsgTemplateTypeEnum wxMsgTemplateTypeEnum = WxMsgTemplateTypeEnum.ENROLL_FAIL_MSG;
            wxMsgTemplateTypeName = wxMsgTemplateTypeEnum.getName();

            String dataStr = String.format(Constant.WX_PUB_ORDER_FAIL_NOTICE_JSON, refundAmtStr,
                    sendOrderVo.getOrderNo(), sendOrderVo.getActiveTitle(), sendOrderVo.getBusinessShortName());
            sendState = wxPubConfig.sendTemplateMsg(openid, wxMsgTemplateTypeEnum, dataStr);

            // 发送活动报名结果系统通知
            NotifyMsgSendDto notifyMsgSendDto = new NotifyMsgSendDto();
            notifyMsgSendDto.setUserId(tbOrderRefundPo.getUserId());
            notifyMsgSendDto.setMsgState(NotifyMsgStateEnum.NO_READ.getValue());
            notifyMsgSendDto.setRoleType(RoleTypeEnum.BUSINESS.getValue());
            notifyMsgSendDto.setMsgType(NotifyMsgTypeEnum.USER_ACTIVE_ORDER_RESULT.getValue());
            notifyMsgSendDto.setContent(String.format(MsgConstant.USER_ACTIVE_ORDER_RESULT_REFUND, sendOrderVo.getActiveTitle()));
            notifyMsgProvider.sendMsg(notifyMsgSendDto);
        }

        if (sendState) {
            log.info("发送【{}】订阅通知成功，userId：{}，orderId：{}", wxMsgTemplateTypeName, tbOrderRefundPo.getUserId(), orderId);
        } else {
            log.error("发送【{}】订阅通知失败，userId：{}，orderId：{}", wxMsgTemplateTypeName, tbOrderRefundPo.getUserId(), orderId);
        }
    }

    @Override
    public Boolean consumerOrderVerifyMsg(Long orderId) {
        // 部分核销的，订单数要算，分销金额算核销部分的
        // 核销成功，需要异步更新商家与经纪人，商家与商户之间的统计信息
        // 商家与商户：总订单数，总订单金额，总补贴金额
        // 商家与经纪人：总分销订单数，总分销订单金额，累计结算分销佣金，累计分销总佣金，累计提现佣金
        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "consumerOrderVerifyMsg:" + orderId);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            return updateBusinessStatisticsData(orderId);
        } finally {
            LockUtils.unlock(lockKey);
        }
    }

    private boolean updateBusinessStatisticsData(Long orderId) {
        TbOrderPo tbOrderPo = baseMapper.selectById(orderId);
        Long businessId = tbOrderPo.getBusinessId();
        Long agentId = tbOrderPo.getAgentId();
        Long agent2Id = tbOrderPo.getAgent2Id();
        Integer orderState = tbOrderPo.getOrderState();
        // 如果订单不是已核销/已完成状态，则不计算
        if (!OrderStateEnum.VERIFIED.getValue().equals(orderState) && !OrderStateEnum.FINISH.getValue().equals(orderState)) {
            log.error("消费核销订单消息失败，订单非已核销/已完成状态，orderId：{}", orderId);
            return true;
        }

        // 总分销订单金额
        BigDecimal totalAgentAmt = BigDecimal.ZERO;
        // 累计分销总佣金
        BigDecimal totalAgentCommissionAmt = BigDecimal.ZERO;
        // 总分销订单金额：二级经纪人
        BigDecimal totalSubAgentAmt = BigDecimal.ZERO;
        // 累计二级经纪人佣金
        BigDecimal totalSubAgentCommissionAmt = BigDecimal.ZERO;
        Map<Long, List<TbOrderItemPo>> merchantOrderItemMap = new HashMap<>();

        // 根据订单id查询已核销的订单项列表数据
        List<TbOrderItemPo> orderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>()
                .eq("del_state", 0)
                .in("sub_order_state", SubOrderStateEnum.VERIFIED.getValue(), SubOrderStateEnum.SETTLED.getValue())
                .eq("order_id", orderId));
        for (TbOrderItemPo orderItemPo : orderItemPos) {
            // 佣金(包含一级经纪人跟二级经纪人的佣金)
            BigDecimal commissionAmt = orderItemPo.getCommissionAmt();
            // 二级经纪人佣金
            BigDecimal subCommissionAmt = orderItemPo.getSubAgentCommissionAmt();

            // 分销订单金额
            BigDecimal distributionOrderAmt = orderItemPo.getDistributionOrderAmt();
            Long merchantId = orderItemPo.getMerchantId();

            if (agentId != null && agentId > 0) {
                totalAgentAmt = totalAgentAmt.add(distributionOrderAmt);
                totalAgentCommissionAmt = totalAgentCommissionAmt.add(commissionAmt);
            }
            if (agent2Id != null && agent2Id > 0) {
                totalSubAgentAmt = totalSubAgentAmt.add(distributionOrderAmt);
                totalSubAgentCommissionAmt = totalSubAgentCommissionAmt.add(subCommissionAmt);
            }

            if (merchantId != null && merchantId > 0) {
                List<TbOrderItemPo> orderItemPoList = merchantOrderItemMap.get(merchantId);
                if (CollectionUtils.isEmpty(orderItemPoList)) {
                    orderItemPoList = new ArrayList<>();
                }
                orderItemPoList.add(orderItemPo);

                merchantOrderItemMap.put(merchantId, orderItemPoList);
            }
        }

        if (agentId != null && agentId > 0) {
            Integer count = orderVerifyMsgMapper.selectCount(new QueryWrapper<TbOrderVerifyMsgPo>().eq("order_id", orderId).eq("type", 2));
            if (count == null || count <= 0) {
                // 更新商家与经纪人之间的总分销订单数，总分销订单金额，累计分销总佣金
                UpdateBusinessAgentOrderDto updateBusinessAgentOrderDto = new UpdateBusinessAgentOrderDto();
                updateBusinessAgentOrderDto.setBusinessId(businessId);
                updateBusinessAgentOrderDto.setUserId(agentId);
                updateBusinessAgentOrderDto.setTotalOrderAmt(totalAgentAmt);
                updateBusinessAgentOrderDto.setTotalCommission(totalAgentCommissionAmt);
                updateBusinessAgentOrderDto.setTotalOrderCount(orderItemPos.size());
                log.error("updateBusinessAgentOrderDto: {}", updateBusinessAgentOrderDto);
                Boolean updateState = businessAgentApi.updateBusinessAgentOrder(updateBusinessAgentOrderDto).unpack();
                if (updateState) {
                    // 添加消费消息记录
                    TbOrderVerifyMsgPo tbOrderVerifyMsgPo = new TbOrderVerifyMsgPo();
                    tbOrderVerifyMsgPo.setOrderId(orderId);
                    tbOrderVerifyMsgPo.setType(2);
                    tbOrderVerifyMsgPo.setCreateTime(LocalDateTime.now());
                    orderVerifyMsgMapper.insert(tbOrderVerifyMsgPo);
                }

                if (agent2Id != null && agent2Id > 0) {
                    // 更新一级经纪人与二级经纪人之间的总分销订单数，总分销订单金额，累计分销总佣金
                    UpdateSubAgentOrderDto updateSubAgentOrderDto = new UpdateSubAgentOrderDto();
                    updateSubAgentOrderDto.setAgentId(agentId);
                    updateSubAgentOrderDto.setUserId(agent2Id);
                    updateSubAgentOrderDto.setTotalOrderAmt(totalSubAgentAmt);
                    updateSubAgentOrderDto.setTotalCommission(totalSubAgentCommissionAmt);
                    updateSubAgentOrderDto.setTotalOrderCount(orderItemPos.size());
                    log.error("updateSubAgentOrderDto: {}", updateSubAgentOrderDto);
                    updateState = businessAgentApi.updateSubAgentOrder(updateSubAgentOrderDto).unpack();
                }
            }
        }

        if (!CollectionUtils.isEmpty(merchantOrderItemMap)) {
            Integer count = orderVerifyMsgMapper.selectCount(new QueryWrapper<TbOrderVerifyMsgPo>().eq("order_id", orderId).eq("type", 1));
            if (count == null || count <= 0) {
                for (Long merchantId : merchantOrderItemMap.keySet()) {
                    List<TbOrderItemPo> orderItemPoList = merchantOrderItemMap.get(merchantId);
                    if (!CollectionUtils.isEmpty(orderItemPoList)) {
                        // 总订单本金
                        BigDecimal totalMerchantAmt = BigDecimal.ZERO;
                        // 总补贴金额
                        BigDecimal totalMerchantSubsidyAmt = BigDecimal.ZERO;
                        for (TbOrderItemPo orderItemPo : orderItemPoList) {
                            // 商户订单本金(按比例分配的用户支付的订单款)
                            BigDecimal merchantAmt = orderItemPo.getMerchantAmt();
                            // 总补贴
                            BigDecimal totalSubsidyAmt = orderItemPo.getTotalSubsidyAmt();

                            totalMerchantAmt = totalMerchantAmt.add(merchantAmt);
                            totalMerchantSubsidyAmt = totalMerchantSubsidyAmt.add(totalSubsidyAmt);
                        }

                        // 更新商家与商户之间的总订单数，总订单本金，总补贴金额
                        UpdateBusinessMerchantOrderDto updateBusinessMerchantOrderDto = new UpdateBusinessMerchantOrderDto();
                        updateBusinessMerchantOrderDto.setBusinessId(businessId);
                        updateBusinessMerchantOrderDto.setMerchantId(merchantId);
                        updateBusinessMerchantOrderDto.setTotalOrderAmt(totalMerchantAmt);
                        updateBusinessMerchantOrderDto.setTotalSubsidyAmt(totalMerchantSubsidyAmt);
                        updateBusinessMerchantOrderDto.setTotalOrderCount(orderItemPoList.size());
                        Boolean updateState = businessMerchantApi.updateBusinessMerchantOrder(updateBusinessMerchantOrderDto).unpack();
                        if (updateState) {
                            // 添加消费消息记录
                            TbOrderVerifyMsgPo tbOrderVerifyMsgPo = new TbOrderVerifyMsgPo();
                            tbOrderVerifyMsgPo.setOrderId(orderId);
                            tbOrderVerifyMsgPo.setType(1);
                            tbOrderVerifyMsgPo.setCreateTime(LocalDateTime.now());
                            orderVerifyMsgMapper.insert(tbOrderVerifyMsgPo);
                        }
                    }
                }
            }
        }
        return true;
    }

    @Override
    public Boolean scanVerifiedOrder() {
        List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                .eq("order_state", OrderStateEnum.VERIFIED.getValue()));
        if (CollectionUtils.isEmpty(tbOrderPos)) {
            return true;
        }

        for (TbOrderPo tbOrderPo : tbOrderPos) {
            if (!updateBusinessStatisticsData(tbOrderPo.getId())) {
                log.error("扫描已核销的订单，更新商家与经纪人，商家与商户之间的统计信息失败，orderId：{}", tbOrderPo.getId());
            }
        }

        return true;
    }

    @Override
    public Boolean systemCancelPay(CancelPayDto cancelPayDto) {
        String orderNo = cancelPayDto.getOrderNo();
        if (StringUtils.isBlank(orderNo)) {
            Throw.isBusinessException("订单号不能为空");
        }

        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "systemCancelPay:" + orderNo);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                    .eq("order_no", orderNo));
            if (CollectionUtils.isEmpty(tbOrderPos)) {
                log.error("系统取消支付失败，未找到订单数据，orderNo：{}", orderNo);
                return false;
            }

            TbOrderPo tbOrderPo = tbOrderPos.get(0);
            if (!OrderStateEnum.WAIT_PAY.getValue().equals(tbOrderPo.getOrderState())) {
                log.error("系统取消支付失败，订单不是待支付状态，orderNo：{}", orderNo);
                return false;
            }

            // 调用hf查单接口，避免临界点出现支付情况，如果查单状态是支付成功，则修改状态为待核销
            HfTradeQuery hfTradeQuery = new HfTradeQuery();
            hfTradeQuery.setOrgReqDate(tbOrderPo.getHfReqDate());
            hfTradeQuery.setOrgReqSeqId(tbOrderPo.getHfReqSeqId());
            JSONObject jsonObject = hfApi.tradeQuery(hfTradeQuery).unpack();
            if (jsonObject == null) {
                log.error("调用hf查单接口异常");
                return false;
            }

            JSONObject dataJSONObject = jsonObject.getJSONObject("data");
            // 交易状态	P：处理中；S：成功；F：失败；I: 初始（初始状态很罕见，请联系汇付技术人员处理）；
            String transStat = dataJSONObject.getString("trans_stat");
            // NOTPAY，订单未支付
            String bankCode = dataJSONObject.getString("bank_code");
            log.info("系统取消支付，订单第三方交易状态：【{}】，orderNo：{}，bankCode：{}", transStat, orderNo, bankCode);
            if ("S".equals(transStat)) {
//                PaySuccessOrderParam paySuccessOrderParam = new PaySuccessOrderParam();
//                paySuccessOrderParam.setId(tbOrderPo.getId());
//                paySuccessOrderParam.setBusinessId(tbOrderPo.getBusinessId());
//                paySuccessOrderParam.setUserId(tbOrderPo.getUserId());
//                paySuccessOrderParam.setOrderTime(tbOrderPo.getOrderTime());
//                paySuccess(paySuccessOrderParam);
                return true;
            }

            if ("P".equals(transStat)) {
                if (!StringUtils.isBlank(bankCode) && "NOTPAY".equals(bankCode)) {
                    CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
                    BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);

                    cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
                    cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                    // 订单备注=超时未支付,系统自动关闭
                    cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.THREE);
                    cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());

                    if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
                        Throw.isBusinessException("取消支付失败");
                    }
                }
                return true;
            }

            if ("F".equals(transStat)) {
                CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
                BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
                cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
                cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                // 订单备注=超时未支付,系统自动关闭
                cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.THREE);
                cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());

                if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
                    log.error("取消订单失败，orderNo：{}", orderNo);
                }

                return true;
            }

            CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
            BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
            cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
            cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
            // 订单备注=超时未支付,系统自动关闭
            cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.THREE);
            cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());

            if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
                Throw.isBusinessException("取消支付失败");
            }

            return true;
        } finally {
            LockUtils.unlock(lockKey);
        }
    }

    @Override
    public Boolean queryOrderPay(OrderPayQueryDto orderPayQueryDto) {
        String orderNo = orderPayQueryDto.getOrderNo();
        if (StringUtils.isBlank(orderNo)) {
            Throw.isBusinessException("订单号不能为空");
        }

        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "queryOrderPay:" + orderNo);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                    .eq("order_no", orderNo));
            if (CollectionUtils.isEmpty(tbOrderPos)) {
                log.error("查单失败，未找到订单数据，orderNo：{}", orderNo);
                return false;
            }

            TbOrderPo tbOrderPo = tbOrderPos.get(0);
            if (!OrderStateEnum.PAYING.getValue().equals(tbOrderPo.getOrderState())) {
                log.error("查单失败，订单不是支付中状态，orderNo：{}", orderNo);
                return true;
            }

            // 调用hf查单接口，避免临界点出现支付情况，如果查单状态是支付成功，则修改状态为待核销
            HfTradeQuery hfTradeQuery = new HfTradeQuery();
            hfTradeQuery.setOrgReqDate(tbOrderPo.getHfReqDate());
            hfTradeQuery.setOrgReqSeqId(tbOrderPo.getHfReqSeqId());
            JSONObject jsonObject = hfApi.tradeQuery(hfTradeQuery).unpack();
            if (jsonObject != null) {
                JSONObject dataJSONObject = jsonObject.getJSONObject("data");
                // 交易状态	P：处理中；S：成功；F：失败；I: 初始（初始状态很罕见，请联系汇付技术人员处理）；
                String transStat = dataJSONObject.getString("trans_stat");
                // NOTPAY，订单未支付
                String bankCode = dataJSONObject.getString("bank_code");
                log.info("查单成功，订单第三方交易状态：【{}】，orderNo：{}，bankCode：{}", transStat, orderNo, bankCode);
                if ("S".equals(transStat)) {
                    PaySuccessOrderParam paySuccessOrderParam = new PaySuccessOrderParam();
                    paySuccessOrderParam.setId(tbOrderPo.getId());
                    paySuccessOrderParam.setOrgOrderState(OrderStateEnum.PAYING.getValue());
                    paySuccessOrderParam.setBusinessId(tbOrderPo.getBusinessId());
                    paySuccessOrderParam.setUserId(tbOrderPo.getUserId());
                    paySuccessOrderParam.setOrderTime(tbOrderPo.getOrderTime());
                    paySuccess(paySuccessOrderParam);
                    return true;
                } else if ("P".equals(transStat)) {
                    if (!StringUtils.isBlank(bankCode) && "NOTPAY".equals(bankCode)) {
                        // 表示已唤醒支付，但未支付关闭第三方支付页面，将支付中--》待支付
                        OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                        orderStateUpdateParam.setId(tbOrderPo.getId());
                        orderStateUpdateParam.setOrgOrderState(OrderStateEnum.PAYING.getValue());
                        // 如果活动已结束或订单超时，则关闭订单
                        if (tbOrderPo.getEndTime().compareTo(LocalDateTime.now()) <= 0
                                || tbOrderPo.getOrderTime().plusMinutes(Constant.ORDER_DELAY_TIME).compareTo(LocalDateTime.now()) <= 0) {
                            orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                            // 订单备注=超时未支付,系统自动关闭
                            orderStateUpdateParam.setOrderNote(OrderNoteConstant.THREE);
                            orderStateUpdateParam.setCloseTime(LocalDateTime.now());
                        } else {
                            orderStateUpdateParam.setOrderState(OrderStateEnum.WAIT_PAY.getValue());
                        }

                        orderStateUpdateParam.setUpdateTime(LocalDateTime.now());
                        baseMapper.updateOrderState(orderStateUpdateParam);
                    }
                    return true;
                } else if ("F".equals(transStat)) {
                    // 查单是支付失败，将支付中--》待支付
                    OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                    orderStateUpdateParam.setId(tbOrderPo.getId());
                    orderStateUpdateParam.setOrgOrderState(OrderStateEnum.PAYING.getValue());
                    // 如果活动已结束或订单超时，则关闭订单
                    if (tbOrderPo.getEndTime().compareTo(LocalDateTime.now()) <= 0
                            || tbOrderPo.getOrderTime().plusMinutes(Constant.ORDER_DELAY_TIME).compareTo(LocalDateTime.now()) <= 0) {
                        orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                        // 订单备注=超时未支付,系统自动关闭
                        orderStateUpdateParam.setOrderNote(OrderNoteConstant.THREE);
                        orderStateUpdateParam.setCloseTime(LocalDateTime.now());
                    } else {
                        orderStateUpdateParam.setOrderState(OrderStateEnum.WAIT_PAY.getValue());
                    }

                    orderStateUpdateParam.setUpdateTime(LocalDateTime.now());
                    baseMapper.updateOrderState(orderStateUpdateParam);
                }
            } else {
                // 没有查到订单，将支付中--》待支付
                OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                orderStateUpdateParam.setId(tbOrderPo.getId());
                orderStateUpdateParam.setOrgOrderState(OrderStateEnum.PAYING.getValue());
                // 如果活动已结束或订单超时，则关闭订单
                if (tbOrderPo.getEndTime().compareTo(LocalDateTime.now()) <= 0
                        || tbOrderPo.getOrderTime().plusMinutes(Constant.ORDER_DELAY_TIME).compareTo(LocalDateTime.now()) <= 0) {
                    orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                    // 订单备注=超时未支付,系统自动关闭
                    orderStateUpdateParam.setOrderNote(OrderNoteConstant.THREE);
                    orderStateUpdateParam.setCloseTime(LocalDateTime.now());
                } else {
                    orderStateUpdateParam.setOrderState(OrderStateEnum.WAIT_PAY.getValue());
                }

                orderStateUpdateParam.setUpdateTime(LocalDateTime.now());
                baseMapper.updateOrderState(orderStateUpdateParam);
            }
        } finally {
            LockUtils.unlock(lockKey);
        }

        return false;
    }

    @Override
    public Boolean toPay(OrderPayQueryDto orderPayQueryDto) {
        String orderNo = orderPayQueryDto.getOrderNo();
        if (StringUtils.isBlank(orderNo)) {
            Throw.isBusinessException("订单号不能为空");
        }

        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "toPay:" + orderNo);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                    .eq("order_no", orderNo));
            if (CollectionUtils.isEmpty(tbOrderPos)) {
                log.error("查单失败，未找到订单数据，orderNo：{}", orderNo);
                Throw.isBusinessException("未找到订单数据");
            }

            TbOrderPo tbOrderPo = tbOrderPos.get(0);
            if (!OrderStateEnum.WAIT_PAY.getValue().equals(tbOrderPo.getOrderState())) {
                log.error("查单失败，订单不是待支付状态，orderNo：{}", orderNo);
                Throw.isBusinessException(ResponseEnums.ORDER_HANDLE);
            }

            // 判断活动是否已结束
            if (tbOrderPo.getEndTime().compareTo(LocalDateTime.now()) <= 0) {
                // 更新订单状态，待支付--》已关闭
                OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                orderStateUpdateParam.setId(tbOrderPo.getId());
                orderStateUpdateParam.setOrgOrderState(OrderStateEnum.WAIT_PAY.getValue());
                orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                // 订单备注=超时未支付,系统自动关闭
                orderStateUpdateParam.setOrderNote(OrderNoteConstant.THREE);
                orderStateUpdateParam.setCloseTime(LocalDateTime.now());
                baseMapper.updateOrderState(orderStateUpdateParam);

                Throw.isBusinessException(ResponseEnums.ORDER_ACTIVE_END);
            }

            // 判断订单是否超时
            if (tbOrderPo.getOrderTime().plusMinutes(Constant.ORDER_DELAY_TIME).compareTo(LocalDateTime.now()) <= 0) {
                // 更新订单状态，待支付--》已关闭
                OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                orderStateUpdateParam.setId(tbOrderPo.getId());
                orderStateUpdateParam.setOrgOrderState(OrderStateEnum.WAIT_PAY.getValue());
                orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                // 订单备注=超时未支付,系统自动关闭
                orderStateUpdateParam.setOrderNote(OrderNoteConstant.THREE);
                orderStateUpdateParam.setCloseTime(LocalDateTime.now());
                baseMapper.updateOrderState(orderStateUpdateParam);

                Throw.isBusinessException(ResponseEnums.ORDER_TIME_OUT);
            }

            // 调用hf查单接口，避免临界点出现支付情况，如果查单状态是支付成功，则修改状态为待核销
            HfTradeQuery hfTradeQuery = new HfTradeQuery();
            hfTradeQuery.setOrgReqDate(tbOrderPo.getHfReqDate());
            hfTradeQuery.setOrgReqSeqId(tbOrderPo.getHfReqSeqId());
            JSONObject jsonObject = hfApi.tradeQuery(hfTradeQuery).unpack();
            if (jsonObject != null) {
                JSONObject dataJSONObject = jsonObject.getJSONObject("data");
                // 交易状态	P：处理中；S：成功；F：失败；I: 初始（初始状态很罕见，请联系汇付技术人员处理）；
                String transStat = dataJSONObject.getString("trans_stat");
                // NOTPAY，订单未支付
                String bankCode = dataJSONObject.getString("bank_code");
                log.info("去支付，查单成功，订单第三方交易状态：【{}】，orderNo：{}，bankCode：{}", transStat, orderNo, bankCode);
                if ("S".equals(transStat)) {
                    PaySuccessOrderParam paySuccessOrderParam = new PaySuccessOrderParam();
                    paySuccessOrderParam.setId(tbOrderPo.getId());
                    paySuccessOrderParam.setOrgOrderState(OrderStateEnum.PAYING.getValue());
                    paySuccessOrderParam.setBusinessId(tbOrderPo.getBusinessId());
                    paySuccessOrderParam.setUserId(tbOrderPo.getUserId());
                    paySuccessOrderParam.setOrderTime(tbOrderPo.getOrderTime());
                    paySuccess(paySuccessOrderParam);

                    Throw.isBusinessException(ResponseEnums.ORDER_PAYED);
                }

                if ("F".equals(transStat)) {
                    // 如果活动已结束或订单超时，则关闭订单
                    if (tbOrderPo.getEndTime().compareTo(LocalDateTime.now()) <= 0
                            || tbOrderPo.getOrderTime().plusMinutes(Constant.ORDER_DELAY_TIME).compareTo(LocalDateTime.now()) <= 0) {
                        // 查单是支付失败，将待支付--》已关闭
                        OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                        orderStateUpdateParam.setId(tbOrderPo.getId());
                        orderStateUpdateParam.setOrgOrderState(OrderStateEnum.WAIT_PAY.getValue());
                        orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                        // 订单备注=超时未支付,系统自动关闭
                        orderStateUpdateParam.setOrderNote(OrderNoteConstant.THREE);
                        orderStateUpdateParam.setCloseTime(LocalDateTime.now());

                        orderStateUpdateParam.setUpdateTime(LocalDateTime.now());
                        baseMapper.updateOrderState(orderStateUpdateParam);

                        Throw.isBusinessException(ResponseEnums.ORDER_TIME_OUT);
                    }
                }
            }
        } finally {
            LockUtils.unlock(lockKey);
        }

        return true;
    }

    @Override
    public List<OrderAvatarVo> listAvatarByDto(OrderDto orderDto) {
        return baseMapper.listAvatarByDto(orderDto);
    }

    @Override
    public Boolean scanWaitePayOrder() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime before = now.plusMinutes(-Constant.ORDER_DELAY_TIME);
        // 扫描待支付订单，如果下单时间超过一定时间，则查单，如果没查到则关闭订单，释放库存（对延时消息消费的补救），如果查到，则根据查单状态修改对应状态
        List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                .eq("order_state", OrderStateEnum.WAIT_PAY.getValue()).le("order_time", before));
        if (CollectionUtils.isEmpty(tbOrderPos)) {
            return true;
        }

        for (TbOrderPo tbOrderPo : tbOrderPos) {
            String orderNo = tbOrderPo.getOrderNo();
            // 查单,如果没查到/支付失败/未支付则关闭订单,释放库存,如果查单状态是支付成功，则修改状态为待核销
            HfTradeQuery hfTradeQuery = new HfTradeQuery();
            hfTradeQuery.setOrgReqDate(tbOrderPo.getHfReqDate());
            hfTradeQuery.setOrgReqSeqId(tbOrderPo.getHfReqSeqId());
            JSONObject jsonObject = hfApi.tradeQuery(hfTradeQuery).unpack();
            if (jsonObject == null) {
                log.error("调用hf查单接口异常");
                continue;
            }

            JSONObject dataJSONObject = jsonObject.getJSONObject("data");
            // 交易状态	P：处理中；S：成功；F：失败；I: 初始（初始状态很罕见，请联系汇付技术人员处理）；
            String transStat = dataJSONObject.getString("trans_stat");
            // NOTPAY，订单未支付
            String bankCode = dataJSONObject.getString("bank_code");
            log.info("扫描待支付订单，订单第三方交易状态：【{}】，orderNo：{}，bankCode：{}", transStat, orderNo, bankCode);
            if ("S".equals(transStat)) {
//                PaySuccessOrderParam paySuccessOrderParam = new PaySuccessOrderParam();
//                paySuccessOrderParam.setId(tbOrderPo.getId());
//                paySuccessOrderParam.setBusinessId(tbOrderPo.getBusinessId());
//                paySuccessOrderParam.setUserId(tbOrderPo.getUserId());
//                paySuccessOrderParam.setOrderTime(tbOrderPo.getOrderTime());
//                paySuccess(paySuccessOrderParam);
                continue;
            }

            if ("P".equals(transStat)) {
                if (!StringUtils.isBlank(bankCode) && "NOTPAY".equals(bankCode)) {
                    CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
                    BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
                    cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
                    cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                    // 订单备注=超时未支付,系统自动关闭
                    cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.THREE);
                    cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());

                    if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
                        log.error("扫描待支付订单，取消订单失败，orderNo：{}", orderNo);
                        continue;
                    }
                }
            }

            if ("F".equals(transStat)) {
                CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
                BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
                cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
                cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                // 订单备注=超时未支付,系统自动关闭
                cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.THREE);
                cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());

                if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
                    log.error("扫描待支付订单，取消订单失败，orderNo：{}", orderNo);
                }
            }

            // 如果没查到单，关单
            CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
            BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
            cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
            cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
            // 订单备注=超时未支付,系统自动关闭
            cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.THREE);
            cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());

            if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
                log.error("扫描待支付订单，取消订单失败，orderNo：{}", orderNo);
            }
        }

        return true;
    }

    @Override
    public Boolean scanPayingOrder() {
        // 扫描支付中订单，如果支付时间超过3分钟，还是支付中，则查单再修改相应的状态
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime before = now.plusMinutes(-3);
        // 扫描待支付订单，如果下单时间超过一定时间，则查单，如果没查到则关闭订单，释放库存（对延时消息消费的补救），如果查到，则根据查单状态修改对应状态
        List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                .eq("order_state", OrderStateEnum.PAYING.getValue()).le("order_time", before));
        if (CollectionUtils.isEmpty(tbOrderPos)) {
            return true;
        }

        for (TbOrderPo tbOrderPo : tbOrderPos) {
            String orderNo = tbOrderPo.getOrderNo();
            // 查单,如果没查到/支付失败/未支付则关闭订单,释放库存,如果查单状态是支付成功，则修改状态为待核销
            HfTradeQuery hfTradeQuery = new HfTradeQuery();
            hfTradeQuery.setOrgReqDate(tbOrderPo.getHfReqDate());
            hfTradeQuery.setOrgReqSeqId(tbOrderPo.getHfReqSeqId());
            JSONObject jsonObject = hfApi.tradeQuery(hfTradeQuery).unpack();
            if (jsonObject == null) {
                log.error("调用hf查单接口异常");
                continue;
            }

            JSONObject dataJSONObject = jsonObject.getJSONObject("data");
            // 交易状态	P：处理中；S：成功；F：失败；I: 初始（初始状态很罕见，请联系汇付技术人员处理）；
            String transStat = dataJSONObject.getString("trans_stat");
            // NOTPAY，订单未支付
            String bankCode = dataJSONObject.getString("bank_code");
            log.info("扫描支付中订单，订单第三方交易状态：【{}】，orderNo：{}，bankCode：{}", transStat, orderNo, bankCode);
            if ("S".equals(transStat)) {
                PaySuccessOrderParam paySuccessOrderParam = new PaySuccessOrderParam();
                paySuccessOrderParam.setId(tbOrderPo.getId());
                paySuccessOrderParam.setOrgOrderState(OrderStateEnum.PAYING.getValue());
                paySuccessOrderParam.setBusinessId(tbOrderPo.getBusinessId());
                paySuccessOrderParam.setUserId(tbOrderPo.getUserId());
                paySuccessOrderParam.setOrderTime(tbOrderPo.getOrderTime());
                paySuccess(paySuccessOrderParam);
                continue;
            }

            if ("P".equals(transStat)) {
                if (!StringUtils.isBlank(bankCode) && "NOTPAY".equals(bankCode)) {
                    CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
                    BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
                    cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
                    cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                    // 订单备注=超时未支付,系统自动关闭
                    cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.THREE);
                    cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());

                    if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
                        log.error("扫描支付中订单，取消订单失败，orderNo：{}", orderNo);
                        continue;
                    }
                }
            }

            if ("F".equals(transStat)) {
                CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
                BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
                cancelWaitPayOrVerifyOrderParam.setOrgOrderState(tbOrderPo.getOrderState());
                cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                // 订单备注=超时未支付,系统自动关闭
                cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.THREE);
                cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());

                if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
                    log.error("扫描支付中订单，取消订单失败，orderNo：{}", orderNo);
                }
            }
        }

        return true;
    }

    private void scanWaiteVerifyOrderHandle(LocalDateTime now, Map<Long, List<TbOrderItemPo>> orderItemMap, TbOrderPo tbOrderPo) {
        Long id = tbOrderPo.getId();
        Integer orderState = tbOrderPo.getOrderState();
        // 是否是零元购活动（1-不是，2-是）
        Integer zeroState = tbOrderPo.getZeroState();
        Long tbOrderRefundId = 0L;
        Long orderId = 0L;
        Integer orderType = tbOrderPo.getOrderType();

        TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

        try {
            BigDecimal totalRefundAmt = BigDecimal.ZERO;

            if (OrderStateEnum.WAIT_VERIFY.getValue().equals(orderState)) {
                // 更新主订单状态=已关闭
                OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                orderStateUpdateParam.setId(tbOrderPo.getId());
                orderStateUpdateParam.setOrgOrderState(OrderStateEnum.WAIT_VERIFY.getValue());
                orderStateUpdateParam.setOrderState(OrderStateEnum.CLOSE.getValue());
                orderStateUpdateParam.setOrderNote(OrderNoteConstant.FIVE);
                orderStateUpdateParam.setCloseTime(now);
                int update = baseMapper.updateOrderState(orderStateUpdateParam);
                if (update == 0) {
                    Throw.isBusinessException("更新主订单状态失败");
                }

                // 更新子订单状态=已过期
                update = orderItemMapper.updateExpireByOrderId(id, now);
                if (update == 0) {
                    Throw.isBusinessException("更新子订单状态失败, orderId=" + id);
                }

                // 退款实付金额
                // 增加全部未核销是否自动退款判断
                ActiveVo activeVo = activeApi.getById(tbOrderPo.getActiveId()).unpack();
                if (activeVo.getAutoRefundEnabled() == null || activeVo.getAutoRefundEnabled() == 1) {
                    // 没有设置（历史数据）或者开启自动退款
                    totalRefundAmt = tbOrderPo.getPayPrice();
                } else if (activeVo.getAutoRefundEnabled() == 0) {
                    // 记录未核销需要打款给商家的记录
                    addOrderUnverifiedRecord(tbOrderPo, tbOrderPo.getPayPrice(), 0);
                }
            } else {
                // 更新主订单状态=已核销
                OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
                orderStateUpdateParam.setId(tbOrderPo.getId());
                orderStateUpdateParam.setOrgOrderState(OrderStateEnum.VERIFYING.getValue());
                orderStateUpdateParam.setOrderState(OrderStateEnum.VERIFIED.getValue());
                orderStateUpdateParam.setVerifyTime(now);
                int update = baseMapper.updateOrderState(orderStateUpdateParam);
                if (update == 0) {
                    Throw.isBusinessException("更新主订单状态失败");
                }

                List<TbOrderItemPo> orderItemPos = orderItemMap.get(id);
                if (CollectionUtils.isEmpty(orderItemPos)) {
                    Throw.isBusinessException("未找到未核销的订单项数据");
                }

                // 更新子订单状态=已过期
                update = orderItemMapper.updateExpireByOrderId(id, now);
                if (update == 0) {
                    Throw.isBusinessException("更新子订单状态失败");
                }

                // 增加核销有效期过后，未核销的部分是否能退款的判断
                if (tbOrderPo.getRefundableExpiredUnused() == null
                        || tbOrderPo.getRefundableExpiredUnused() == 0) {
                    // 退款未核销的分销金额
                    for (TbOrderItemPo orderItemPo : orderItemPos) {
                        if (SubOrderStateEnum.WAIT_VERIFY.getValue().equals(orderItemPo.getSubOrderState())) {
                            BigDecimal distributionOrderAmt = orderItemPo.getDistributionOrderAmt();
                            totalRefundAmt = totalRefundAmt.add(distributionOrderAmt);
                        }
                    }
                } else if (tbOrderPo.getRefundableExpiredUnused() == 1) {
                    BigDecimal recoverAmt = BigDecimal.ZERO;

                    // 部分核销不退款改成根据分组内生效
                    Map<Integer, List<TbOrderItemPo>> itemGroups = orderItemPos.stream()
                            .collect(Collectors.groupingBy(TbOrderItemPo::getItemGroup));
                    for (Map.Entry<Integer, List<TbOrderItemPo>> itemGroup : itemGroups.entrySet()) {
                        // 判断分组内是否存在核销的记录，如果有，这个分组的子单不退款
                        boolean canRefund = itemGroupCanRefund(itemGroup.getValue());
                        if (canRefund) {
                            BigDecimal groupRefundAmt = getTotalRefundAmt(itemGroup.getValue());
                            totalRefundAmt = totalRefundAmt.add(groupRefundAmt);
                        } else {
                            for (TbOrderItemPo orderItemPo : itemGroup.getValue()) {
                                if (SubOrderStateEnum.WAIT_VERIFY.getValue().equals(orderItemPo.getSubOrderState())) {
                                    BigDecimal distributionOrderAmt = orderItemPo.getDistributionOrderAmt();
                                    recoverAmt = recoverAmt.add(distributionOrderAmt);
                                }
                            }
                        }
                    }
//                    for (TbOrderItemPo orderItemPo : orderItemPos) {
//                        if (SubOrderStateEnum.WAIT_VERIFY.getValue().equals(orderItemPo.getSubOrderState())) {
//                            BigDecimal distributionOrderAmt = orderItemPo.getDistributionOrderAmt();
//                            recoverAmt = recoverAmt.add(distributionOrderAmt);
//                        }
//                    }
                    // 记录未核销需要打款给商家的记录
                    addOrderUnverifiedRecord(tbOrderPo, recoverAmt, 1);
                }

                orderId = tbOrderPo.getId();
            }

            // 积分订单，过期未核销，不退积分
            if (Objects.equals(orderType, ActiveTypeEnum.POINTS.getValue())) {
                totalRefundAmt = BigDecimal.ZERO;
            }

            if ((totalRefundAmt != null && totalRefundAmt.compareTo(BigDecimal.ZERO) > 0)
                    || ZeroStateEnum.YES.getValue().equals(zeroState)) {
                TbOrderRefundPo tbOrderRefundPo = new TbOrderRefundPo();
                tbOrderRefundPo.setBusinessId(tbOrderPo.getBusinessId());
                tbOrderRefundPo.setUserId(tbOrderPo.getUserId());
                tbOrderRefundPo.setOrderId(tbOrderPo.getId());
                // 退款类型(1-用户申请退款，2-核销过期自动退)
                tbOrderRefundPo.setRefundType(RefundTypeEnum.VERIFY_EXPIRE.getValue());
                tbOrderRefundPo.setOrgReqDate(tbOrderPo.getHfReqDate());
                tbOrderRefundPo.setOrgReqSeqId(tbOrderPo.getHfReqSeqId());
                tbOrderRefundPo.setRefundAmt(totalRefundAmt);
                // 退款交易状态(1-待处理，2-处理中，3-成功，4-失败)
                tbOrderRefundPo.setRefundState(OrderRefundStateEnum.WAIT.getValue());
                tbOrderRefundPo.setRefundApplyTime(LocalDateUtil.getNowLocalDateTime());

                int insert = orderRefundMapper.insert(tbOrderRefundPo);
                if (insert == 0) {
                    Throw.isBusinessException("取消失败");
                }

                tbOrderRefundId = tbOrderRefundPo.getId();
            }

            transactionManager.commit(transaction);
        } catch (Exception e) {
            //回滚事务
            transactionManager.rollback(transaction);
            log.error("<扫描待核销/核销中的订单处理>事务异常回滚", e);
            Throw.isBusinessException(e.getMessage());
        }

        if (tbOrderRefundId != null && tbOrderRefundId > 0) {
            orderRefundMsgProvider.sendMsg(tbOrderRefundId);
        }

        if (orderId != null && orderId > 0) {
            // 如果订单是已核销状态，发送mq消息，核销成功，需要异步更新商家与经纪人，商家与商户之间的统计信息
            orderVerifyMsgProvider.sendMsg(orderId);
        }
    }

    private BigDecimal getTotalRefundAmt(List<TbOrderItemPo> orderItemPos) {
        BigDecimal totalRefundAmt = BigDecimal.ZERO;
        for (TbOrderItemPo orderItemPo : orderItemPos) {
            if (SubOrderStateEnum.WAIT_VERIFY.getValue().equals(orderItemPo.getSubOrderState())) {
                BigDecimal distributionOrderAmt = orderItemPo.getDistributionOrderAmt();
                totalRefundAmt = totalRefundAmt.add(distributionOrderAmt);
            }
        }
        return totalRefundAmt;
    }

    private boolean itemGroupCanRefund(List<TbOrderItemPo> orderItems) {
        long count = orderItems.stream()
                .filter(e -> e.getSubOrderState().equals(SubOrderStateEnum.WAIT_VERIFY.getValue()))
                .count();
        return count == orderItems.size();
    }

    private void addOrderUnverifiedRecord(TbOrderPo tbOrderPo, BigDecimal recoverAmt, Integer isPartial) {
        if (recoverAmt.compareTo(BigDecimal.ZERO) <= 0) {
            log.error("orderId:{} recoverAmt:{}", tbOrderPo.getId(), recoverAmt);
            return;
        }
        TbOrderUnverifiedRecordPo tbOrderUnverifiedRecordPo = new TbOrderUnverifiedRecordPo();
        tbOrderUnverifiedRecordPo.setOrderId(tbOrderPo.getId());
        tbOrderUnverifiedRecordPo.setBusinessId(tbOrderPo.getBusinessId());
        tbOrderUnverifiedRecordPo.setIsPartial(isPartial);
        tbOrderUnverifiedRecordPo.setRecoverAmt(recoverAmt);
        orderUnverifiedRecordService.addOrderUnverifiedRecord(tbOrderUnverifiedRecordPo);
    }

    /**
     * 如果活动结束,则处理报名活动订单的未满自动退和阶梯
     * 否则处理核销结算
     * 如果活动核销结算,则处理待核销/核销中订单退款
     */
    @Override
    public Boolean scanEndVerifyOrder() {
        // 查询待核销、核销中、已核销的订单
        LocalDateTime now = LocalDateTime.now();
        List<TbOrderPo> tbOrderPos = baseMapper.selectList(new QueryWrapper<TbOrderPo>().eq("del_state", 0)
                .in("order_state", Arrays.asList(OrderStateEnum.WAIT_VERIFY.getValue(),
                        OrderStateEnum.VERIFYING.getValue(),
                        OrderStateEnum.VERIFIED.getValue()))
        );

        if (CollectionUtils.isEmpty(tbOrderPos)) {
            return true;
        }

        Map<Long, List<TbOrderPo>> orderMap = tbOrderPos.stream().collect(Collectors.groupingBy(TbOrderPo::getActiveId));

        // 获取开启了阶梯价格的活动的阶梯价格配置列表
        Map<Long, List<ActiveStepPriceVo>> activeStepPriceMap = new HashMap<>();
        List<TbOrderPo> stepPriceOrders = tbOrderPos.stream()
                .filter(tbOrderPo -> StepPriceStateEnum.YES.getValue().equals(tbOrderPo.getStepPriceState()))
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(stepPriceOrders)) {
            List<Long> activeIds = stepPriceOrders.stream().map(TbOrderPo::getActiveId).collect(Collectors.toList());
            List<ActiveStepPriceVo> activeStepPriceVos = activeStepPriceApi.listByActiveIds(activeIds).unpack();
            if (!CollectionUtils.isEmpty(activeStepPriceVos)) {
                activeStepPriceMap = activeStepPriceVos.stream().collect(Collectors.groupingBy(ActiveStepPriceVo::getActiveId));
            }
        }

        Map<Long, List<TbOrderItemPo>> orderItemMapByActiveId = new HashMap<>();
        Map<Long, List<TbOrderItemPo>> orderItemMapByOrderId = new HashMap<>();
        // 根据订单id查询订单项数据
        List<Long> orderIds = tbOrderPos.stream().map(TbOrderPo::getId).collect(Collectors.toList());
        List<TbOrderItemPo> orderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
                .in("order_id", orderIds));
        if (!CollectionUtils.isEmpty(orderItemPos)) {
            orderItemMapByActiveId = orderItemPos.stream().collect(Collectors.groupingBy(TbOrderItemPo::getActiveId));
            orderItemMapByOrderId = orderItemPos.stream().collect(Collectors.groupingBy(TbOrderItemPo::getOrderId));
        }

        List<Long> businessIds = tbOrderPos.stream().map(TbOrderPo::getBusinessId).collect(Collectors.toList());
        List<Long> merchantIds = new ArrayList<>();
        List<Long> agentIds = tbOrderPos.stream()
                .filter(order -> order.getAgentId() != null && order.getAgentId() > 0)
                .map(TbOrderPo::getAgentId)
                .collect(Collectors.toList());

        // 查询商家数据
        Map<Long, BusinessDetailVo> businessMap = new HashMap<>();
        List<BusinessDetailVo> businessVos = businessApi.listDetailByIds(businessIds).unpack();
        if (!CollectionUtils.isEmpty(businessVos)) {
            businessMap = businessVos.stream().collect(Collectors.toMap(BusinessDetailVo::getId, Function.identity(), (k1, k2) -> k1));
        }

        // 已核销的订单项数据
        orderItemPos = orderItemPos.stream().filter(orderItemPo -> SubOrderStateEnum.VERIFIED.getValue().equals(orderItemPo.getSubOrderState())).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(orderItemPos)) {
            merchantIds = orderItemPos.stream().map(TbOrderItemPo::getMerchantId).collect(Collectors.toList());
        }

        // 查询商家的自有商户
        Map<Long, BusinessMerchantVo> businessMerchantVoMap = new HashMap<>();
        List<BusinessMerchantVo> ownBusinessMerchants = businessMerchantApi.listOwnMerchantByBusinessIds(businessIds).unpack();
        if (!CollectionUtils.isEmpty(ownBusinessMerchants)) {
            businessMerchantVoMap = ownBusinessMerchants.stream().collect(Collectors.toMap(BusinessMerchantVo::getMerchantId, Function.identity(), (k1, k2) -> k2));
            merchantIds.addAll(ownBusinessMerchants.stream().map(BusinessMerchantVo::getMerchantId).collect(Collectors.toList()));
        }

        // 查询商户数据
        Map<Long, MerchantDetailVo> merchantMap = new HashMap<>();
        List<MerchantDetailVo> merchantVos = merchantApi.listDetailByIds(merchantIds).unpack();
        if (!CollectionUtils.isEmpty(merchantVos)) {
            merchantMap = merchantVos.stream().collect(Collectors.toMap(MerchantDetailVo::getId, Function.identity(), (k1, k2) -> k1));
        }

        Map<Long, List<AgentEnterApplyDetailVo>> agentEnterApplyDetailMap = new HashMap<>();
        Map<Long, AppUserVo> agentUserMap = new HashMap<>();

        if (!CollectionUtils.isEmpty(agentIds)) {
            // 查询经纪人入驻的列表，获取对应的落地会员号
            AgentEnterApplyDetailDto agentEnterApplyDetailDto = new AgentEnterApplyDetailDto();
            agentEnterApplyDetailDto.setState(AgentEnterStateEnum.SIGN_SUCCESS.getValue());
            agentEnterApplyDetailDto.setUserIds(agentIds);
            List<AgentEnterApplyDetailVo> agentEnterApplyVos = agentEnterApplyApi.listByDto(agentEnterApplyDetailDto).unpack();
            if (!CollectionUtils.isEmpty(agentEnterApplyVos)) {
                agentEnterApplyDetailMap = agentEnterApplyVos.stream()
                        .collect(Collectors.groupingBy(AgentEnterApplyDetailVo::getUserId));
            }

            // 查询经纪人数据
            List<AppUserVo> agentUsers = appUserApi.listByUserIds(agentIds).unpack();
            if (!CollectionUtils.isEmpty(agentUsers)) {
                agentUserMap = agentUsers.stream().collect(Collectors.toMap(AppUserVo::getId, Function.identity(), (k1, k2) -> k2));
            }
        }

        for (Long activeId : orderMap.keySet()) {
            List<TbOrderPo> tbOrderPoList = orderMap.get(activeId);
            Map<Long, TbOrderPo> orderMapById = tbOrderPoList.stream().collect(Collectors.toMap(TbOrderPo::getId, Function.identity(), (k1, k2) -> k2));

            TbOrderPo tbOrderPo = tbOrderPoList.get(0);
            Integer noFullAutoRefundState = tbOrderPo.getNoFullAutoRefundState();
            Integer stepPriceState = tbOrderPo.getStepPriceState();
            LocalDateTime endTime = tbOrderPo.getEndTime();
            List<TbOrderItemPo> tbOrderItemPos = orderItemMapByActiveId.get(activeId);

            // 如果活动结束,则处理报名活动订单的未满自动退和阶梯
            if (endTime.isBefore(now)) {
                if (ActiveTypeEnum.ENROLL.getValue().equals(tbOrderPo.getOrderType())
                        // 团购+报名
                        && ActiveTypeEnum.GROUP_ENROLL.getValue().equals(tbOrderPo.getOrderType())) {
                    // 判断订单活动是否开启了未满员自动退款
//                    if (NoFullAutoRefundStateEnum.YES.getValue().equals(noFullAutoRefundState)) {
//                        int enrollNum;
//                        // 判断是否开启了阶梯价格
//                        if (StepPriceStateEnum.YES.getValue().equals(stepPriceState)) {
//                            // 如果开启了，获取阶梯最少人数
//                            List<ActiveStepPriceVo> activeStepPriceVos = activeStepPriceMap.get(activeId);
//                            List<ActiveStepPriceVo> sortActiveStepPriceVos = activeStepPriceVos.stream()
//                                    .sorted(Comparator.comparing(ActiveStepPriceVo::getEnrollNum))
//                                    .collect(Collectors.toList());
//                            enrollNum = sortActiveStepPriceVos.get(0).getEnrollNum();
//                        } else {
//                            // 如果没开启，获取活动固定人数
//                            enrollNum = tbOrderPo.getTotalStock();
//                        }
//
//                        // 报名成功的用户订单（包含取消时间晚于活动结束时间的取消参与用户）
//                        List<TbOrderItemPo> enrolledSuccessOrderItems = new ArrayList<>();
//                        for (TbOrderItemPo tbOrderItemPo : tbOrderItemPos) {
//                            // 如果用户取消参与活动，且活动结束时间不早于取消活动时间，则不计入报名用户数
//                            if (SubOrderStateEnum.CANCEL.getValue().equals(tbOrderItemPo.getSubOrderState())
//                                    && endTime.compareTo(tbOrderItemPo.getCancelTime()) >= 0) {
//                                continue;
//                            }
//
//                            enrolledSuccessOrderItems.add(tbOrderItemPo);
//                        }
//                        // 报名成功的主订单id集合（以前报名订单只有一个子单，所以用子单判断（是否达到报名数量）没问题，现在团购+报名类型的订单会有多个子单，需要统一用主订单数量来判断）
//                        Set<Long> enrolledSuccessOrderIds = enrolledSuccessOrderItems.stream().map(TbOrderItemPo::getOrderId).collect(Collectors.toSet());
//                        if (!CollectionUtils.isEmpty(enrolledSuccessOrderIds)) {
//                            if (enrolledSuccessOrderIds.size() < enrollNum) {
//                                // 如果未满员，将待核销的订单的实付金额退还，修改主订单状态=已关闭，子订单状态=已取消，
//                                Map<Long, List<TbOrderItemPo>> enrolledOrderItemMapByOrderId = enrolledSuccessOrderItems.stream()
//                                        .collect(Collectors.groupingBy(TbOrderItemPo::getOrderId));
//                                for (Long orderId : enrolledOrderItemMapByOrderId.keySet()) {
//                                    // 修改主订单状态=已关闭
//                                    TbOrderPo tbOrder = orderMapById.get(orderId);
//                                    if (tbOrder != null) {
//                                        if (!ActiveTypeEnum.ENROLL.getValue().equals(tbOrder.getOrderType())) {
//                                            continue;
//                                        }
//                                        if (!OrderStateEnum.WAIT_VERIFY.getValue().equals(tbOrder.getOrderState())) {
//                                            continue;
//                                        }
//
//                                        CancelWaitPayOrVerifyOrderParam cancelWaitPayOrVerifyOrderParam = new CancelWaitPayOrVerifyOrderParam();
//                                        BeanUtils.copyProperties(tbOrderPo, cancelWaitPayOrVerifyOrderParam);
//                                        cancelWaitPayOrVerifyOrderParam.setOrgOrderState(OrderStateEnum.WAIT_VERIFY.getValue());
//                                        // 更新订单状态，待核销--》已关闭
//                                        cancelWaitPayOrVerifyOrderParam.setOrderState(OrderStateEnum.CLOSE.getValue());
//                                        cancelWaitPayOrVerifyOrderParam.setOrderNote(OrderNoteConstant.FOUR);
//                                        cancelWaitPayOrVerifyOrderParam.setCloseTime(LocalDateTime.now());
//
//                                        if (!cancelWaitPayOrVerifyOrder(cancelWaitPayOrVerifyOrderParam)) {
//                                            log.error("订单未满员退款,修改关闭状态失败, cancelWaitPayOrVerifyOrderParam:{}", JSON.toJSONString(cancelWaitPayOrVerifyOrderParam));
//                                            continue;
//                                        }
//
//                                        // 退款
//                                        TbOrderRefundPo tbOrderRefundPo = new TbOrderRefundPo();
//                                        tbOrderRefundPo.setBusinessId(tbOrder.getBusinessId());
//                                        tbOrderRefundPo.setUserId(tbOrder.getUserId());
//                                        tbOrderRefundPo.setOrderId(tbOrder.getId());
//                                        // 退款类型(退款类型(1-用户申请退款，2-核销过期自动退,3-报名活动未满员自动退，4-阶梯价格退还))
//                                        tbOrderRefundPo.setRefundType(RefundTypeEnum.NO_FULL.getValue());
//                                        tbOrderRefundPo.setOrgReqDate(tbOrder.getHfReqDate());
//                                        tbOrderRefundPo.setOrgReqSeqId(tbOrder.getHfReqSeqId());
//                                        tbOrderRefundPo.setRefundAmt(tbOrder.getPayPrice());
//                                        // 退款交易状态(1-待处理，2-处理中，3-成功，4-失败)
//                                        tbOrderRefundPo.setRefundState(OrderRefundStateEnum.WAIT.getValue());
//                                        tbOrderRefundPo.setRefundApplyTime(LocalDateUtil.getNowLocalDateTime());
//
//                                        int insert = orderRefundMapper.insert(tbOrderRefundPo);
//                                        if (insert == 0) {
//                                            log.error("订单未满员退款,增加退款记录失败, tbOrderRefundPo:{}", JSON.toJSONString(tbOrderRefundPo));
//                                            continue;
//                                        }
//
//                                        orderRefundMsgProvider.sendMsg(tbOrderRefundPo.getId());
//                                    }
//                                }
//
//                                continue;
//                            }
//                        }
//                    }

                    // 判断是否开启了阶梯价格
//                    if (StepPriceStateEnum.YES.getValue().equals(stepPriceState)) {
//                        // 重新查询该活动待核销/已核销/已过期/已取消的报名活动订单项列表
//                        List<TbOrderItemPo> verifyOrderItemPos = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>().eq("del_state", 0)
//                                .eq("active_id", activeId)
//                                .in("order_type", Arrays.asList(ActiveTypeEnum.ENROLL.getValue(), ActiveTypeEnum.GROUP_ENROLL.getValue()))
//                                .in("sub_order_state", Arrays.asList(SubOrderStateEnum.WAIT_VERIFY.getValue(),
//                                        SubOrderStateEnum.VERIFIED.getValue(),
//                                        SubOrderStateEnum.CANCEL.getValue(),
//                                        SubOrderStateEnum.EXPIRED.getValue()))
//                        );
//
//                        // 报名成功的用户订单（包含取消时间晚于活动结束时间的取消参与用户）
//                        List<TbOrderItemPo> enrolledSuccessOrderItems = new ArrayList<>();
//                        for (TbOrderItemPo tbOrderItemPo : verifyOrderItemPos) {
//                            // 如果用户取消参与活动，且活动结束时间不早于取消活动时间，则不计入报名用户数
//                            if (SubOrderStateEnum.CANCEL.getValue().equals(tbOrderItemPo.getSubOrderState())
//                                    && endTime.compareTo(tbOrderItemPo.getCancelTime()) >= 0) {
//                                continue;
//                            }
//
//                            enrolledSuccessOrderItems.add(tbOrderItemPo);
//                        }
//                        int enrolledNum = getOrderSize(enrolledSuccessOrderItems); // enrolledSuccessOrderItems.size();
//
//                        List<EnrollOrderStepReturnNotifyParam> enrollOrderStepReturnNotifyParams = new ArrayList<>();
//
//                        Map<Long, List<TbOrderItemPo>> verifyOrderItemMapByOrderId = verifyOrderItemPos.stream().collect(Collectors.groupingBy(TbOrderItemPo::getOrderId));
//                        for (Long orderId : verifyOrderItemMapByOrderId.keySet()) {
//                            TbOrderPo orderPo = orderMapById.get(orderId);
//                            BigDecimal totalReturnAmt = BigDecimal.ZERO;
//                            // 通知中可返金额
//                            BigDecimal totalNoticeReturnAmt = BigDecimal.ZERO;
//
//                            // 有核销的报名订单
//                            List<TbOrderItemPo> orderItemPoList = verifyOrderItemMapByOrderId.get(orderId);
//                            // 获取阶梯配置，遍历获取对应的层级
//                            List<ActiveStepPriceVo> activeStepPriceVos = activeStepPriceMap.get(activeId);
//                            if (!CollectionUtils.isEmpty(activeStepPriceVos)) {
//                                // 根据阶梯报名人数正序
//                                activeStepPriceVos = activeStepPriceVos.stream()
//                                        .sorted(Comparator.comparing(ActiveStepPriceVo::getEnrollNum))
//                                        .collect(Collectors.toList());
//
//                                // 活动报名价格
//                                BigDecimal activePrice = orderPo.getActivePrice();
//                                // 可返金额
//                                BigDecimal returnAmt = BigDecimal.ZERO;
//                                for (ActiveStepPriceVo activeStepPriceVo : activeStepPriceVos) {
//                                    Integer enrollNum = activeStepPriceVo.getEnrollNum();
//                                    BigDecimal enrollPrice = activeStepPriceVo.getEnrollPrice();
//
//                                    if (enrolledNum >= enrollNum) {
//                                        returnAmt = activePrice.subtract(enrollPrice)
//                                                .multiply(BigDecimal.valueOf(orderPo.getOrderNum()));
//                                    }
////
////                                    // 取下一阶级的报名人数对比，如果都没匹配上，则表示已满员 TODO
////                                    if (enrolledNum <= enrollNum) {
////                                        // 计算可返金额=当前报名价格-对应阶级报名价格
////                                        returnAmt = activePrice.subtract(enrollPrice);
////                                        break;
////                                    }
//                                }
//
//                                if (returnAmt.compareTo(BigDecimal.ZERO) > 0) {
//                                    // 更新报名成功的可返还金额
//                                    for (TbOrderItemPo tbOrderItemPo : orderItemPoList) {
//                                        // 只退还已核销的金额，待核销的子订单后面单独退分销金额，已过期和已取消的都退过
//                                        if (SubOrderStateEnum.VERIFIED.getValue().equals(tbOrderItemPo.getSubOrderState())) {
//                                            totalNoticeReturnAmt = totalNoticeReturnAmt.add(returnAmt);
//
//                                            // 移到订单核销的时候触发记录返现: com.cq.hd.order.service.OrderStepPriceCashbackService.applyCashbackWhenVerified
////                                            // 更新可返还金额
////                                            BigDecimal merchantAmt = tbOrderItemPo.getMerchantAmt();
////                                            BigDecimal merchantAmtTmp = merchantAmt.subtract(returnAmt);
////                                            // 如果本金小于可返金额，则能返多少就返多少
////                                            if (merchantAmtTmp.compareTo(BigDecimal.ZERO) < 0) {
////                                                merchantAmtTmp = BigDecimal.ZERO;
////                                                returnAmt = merchantAmt;
////                                            }
////                                            orderItemMapper.updateReturnAmt(tbOrderItemPo.getId(), returnAmt, merchantAmtTmp);
////                                            // 累加子订单可返还金额，一笔订单只做一次退款
////                                            totalReturnAmt = totalReturnAmt.add(returnAmt);
//                                        } else if (SubOrderStateEnum.WAIT_VERIFY.getValue().equals(tbOrderItemPo.getSubOrderState())) {
//                                            totalNoticeReturnAmt = totalNoticeReturnAmt.add(returnAmt);
//                                        }
//                                    }
//                                }
//                            }
//
//                            if (totalNoticeReturnAmt.compareTo(BigDecimal.ZERO) > 0) {
//                                EnrollOrderStepReturnNotifyParam enrollOrderStepReturnNotifyParam = new EnrollOrderStepReturnNotifyParam();
//                                enrollOrderStepReturnNotifyParam.setOrderId(orderId);
//                                enrollOrderStepReturnNotifyParam.setUserId(orderPo.getUserId());
//                                enrollOrderStepReturnNotifyParam.setReturnAmt(totalNoticeReturnAmt);
//                                enrollOrderStepReturnNotifyParam.setEnrolledNum(enrolledNum);
//                                enrollOrderStepReturnNotifyParam.setActiveTitle(orderPo.getActiveTitle());
//                                enrollOrderStepReturnNotifyParams.add(enrollOrderStepReturnNotifyParam);
//                            }
//
//                            // 移到订单核销的时候触发记录返现: com.cq.hd.order.service.OrderStepPriceCashbackService.applyCashbackWhenVerified
////                            if (totalReturnAmt.compareTo(BigDecimal.ZERO) > 0) {
////                                // 查询是否有退还
////                                Integer count = orderRefundMapper.selectCount(new QueryWrapper<TbOrderRefundPo>().eq("del_state", 0)
////                                        .eq("refund_type", RefundTypeEnum.STEP_PRICE.getValue())
////                                        .eq("user_id", orderPo.getUserId())
////                                        .eq("order_id", orderId));
////                                if (count == null || count <= 0) {
////                                    // 阶梯价格退还
////                                    TbOrderRefundPo tbOrderRefundPo = new TbOrderRefundPo();
////                                    tbOrderRefundPo.setBusinessId(orderPo.getBusinessId());
////                                    tbOrderRefundPo.setUserId(orderPo.getUserId());
////                                    tbOrderRefundPo.setOrderId(orderId);
////                                    // 退款类型(退款类型(1-用户申请退款，2-核销过期自动退,3-报名活动未满员自动退，4-阶梯价格退还))
////                                    tbOrderRefundPo.setRefundType(RefundTypeEnum.STEP_PRICE.getValue());
////                                    tbOrderRefundPo.setOrgReqDate(orderPo.getHfReqDate());
////                                    tbOrderRefundPo.setOrgReqSeqId(orderPo.getHfReqSeqId());
////                                    tbOrderRefundPo.setRefundAmt(totalReturnAmt);
////                                    // 退款交易状态(1-待处理，2-处理中，3-成功，4-失败)
////                                    tbOrderRefundPo.setRefundState(OrderRefundStateEnum.WAIT.getValue());
////                                    tbOrderRefundPo.setRefundApplyTime(LocalDateUtil.getNowLocalDateTime());
////
////                                    int insert = orderRefundMapper.insert(tbOrderRefundPo);
////                                    if (insert == 0) {
////                                        log.error("阶梯价格退还失败，添加退款记录失败，orderId：{}", orderId);
////                                        continue;
////                                    }
////
////                                    orderRefundMsgProvider.sendMsg(tbOrderRefundPo.getId());
////
////                                    // 发送活动返现系统通知
////                                    NotifyMsgSendDto notifyMsgSendDto = new NotifyMsgSendDto();
////                                    notifyMsgSendDto.setUserId(orderPo.getUserId());
////                                    notifyMsgSendDto.setRoleType(RoleTypeEnum.BUSINESS.getValue());
////                                    notifyMsgSendDto.setMsgType(NotifyMsgTypeEnum.USER_ENROLL_ORDER_RETURN.getValue());
////                                    notifyMsgSendDto.setContent(String.format(MsgConstant.USER_ENROLL_ORDER_RETURN, tbOrderPo.getActiveTitle(), totalReturnAmt));
////                                    notifyMsgSendDto.setMsgState(NotifyMsgStateEnum.NO_READ.getValue());
////                                    notifyMsgProvider.sendMsg(notifyMsgSendDto);
////                                }
////                            }
//                        }
//
//                        // 发送活动报名结果系统通知
//                        if (!CollectionUtils.isEmpty(enrollOrderStepReturnNotifyParams)) {
//                            for (EnrollOrderStepReturnNotifyParam enrollOrderStepReturnNotifyParam : enrollOrderStepReturnNotifyParams) {
//                                NotifyMsgSendDto notifyMsgSendDto = new NotifyMsgSendDto();
//                                notifyMsgSendDto.setUserId(enrollOrderStepReturnNotifyParam.getUserId());
//                                notifyMsgSendDto.setMsgState(NotifyMsgStateEnum.NO_READ.getValue());
//                                notifyMsgSendDto.setRoleType(RoleTypeEnum.BUSINESS.getValue());
//                                notifyMsgSendDto.setMsgType(NotifyMsgTypeEnum.USER_ACTIVE_ORDER_RESULT.getValue());
//                                notifyMsgSendDto.setContent(String.format(MsgConstant.USER_ACTIVE_ORDER_RESULT_STEP_FULL, enrollOrderStepReturnNotifyParam.getActiveTitle(),
//                                        enrollOrderStepReturnNotifyParam.getEnrolledNum(),
//                                        enrollOrderStepReturnNotifyParam.getReturnAmt().toString()));
//                                notifyMsgProvider.sendMsg(notifyMsgSendDto);
//                            }
//                        }
//                    } else {
//                        // 固定报名人数，如果满员，发送系统通知
//                        // 满员（固定人数）：您参与的报名活动【xxxxx】召集满小伙伴啦~
//                        // 固定报名人数
//                        int enrollNum = tbOrderPo.getTotalStock();
//
//                        // 报名成功的用户订单（包含取消时间晚于活动结束时间的取消参与用户）
//                        List<TbOrderItemPo> enrolledSuccessOrderItems = new ArrayList<>();
//                        for (TbOrderItemPo tbOrderItemPo : tbOrderItemPos) {
//                            // 如果用户取消参与活动，且活动结束时间不早于取消活动时间，则不计入报名用户数
//                            if (SubOrderStateEnum.CANCEL.getValue().equals(tbOrderItemPo.getSubOrderState())
//                                    && endTime.compareTo(tbOrderItemPo.getCancelTime()) >= 0) {
//                                continue;
//                            }
//
//                            enrolledSuccessOrderItems.add(tbOrderItemPo);
//                        }
//
//                        if (getOrderSize(enrolledSuccessOrderItems) >= enrollNum) {
//                            Map<Long, List<TbOrderItemPo>> enrolledSuccessOrderItemMapByOrderId = enrolledSuccessOrderItems.stream().collect(Collectors.groupingBy(TbOrderItemPo::getOrderId));
//                            for (Long orderId : enrolledSuccessOrderItemMapByOrderId.keySet()) {
//                                TbOrderPo tbOrder = orderMapById.get(orderId);
//                                if (tbOrder != null) {
//                                    String activeTitle = tbOrder.getActiveTitle();
//
//                                    // 发送活动报名结果系统通知
//                                    NotifyMsgSendDto notifyMsgSendDto = new NotifyMsgSendDto();
//                                    notifyMsgSendDto.setUserId(tbOrder.getUserId());
//                                    notifyMsgSendDto.setMsgState(NotifyMsgStateEnum.NO_READ.getValue());
//                                    notifyMsgSendDto.setRoleType(RoleTypeEnum.BUSINESS.getValue());
//                                    notifyMsgSendDto.setMsgType(NotifyMsgTypeEnum.USER_ACTIVE_ORDER_RESULT.getValue());
//                                    notifyMsgSendDto.setContent(String.format(MsgConstant.USER_ACTIVE_ORDER_RESULT_FULL, activeTitle));
//                                    notifyMsgProvider.sendMsg(notifyMsgSendDto);
//                                }
//                            }
//                        }
//                    }
                }
            }

            for (TbOrderPo orderPo : tbOrderPoList) {
                // 如果是待核销订单，则修改子订单状态=已过期.主订单状态=已关闭,并退款
                // 如果是核销中订单，则修改子订单状态=已过期.主订单状态=已核销,并退款
                if (OrderStateEnum.WAIT_VERIFY.getValue().equals(orderPo.getOrderState())
                        || OrderStateEnum.VERIFYING.getValue().equals(orderPo.getOrderState())) {
                    LocalDateTime validEndTime = orderPo.getValidEndTime();
                    // 如果活动核销时间结束,则处理待核销和核销中的活动订单
                    if (validEndTime.isBefore(now)) {
                        scanWaiteVerifyOrderHandle(now, orderItemMapByOrderId, orderPo);
                        continue;
                    }
                }

                // 如果是已核销订单，根据订单核销完成时间，T+1，做结算，分钱+给商户发送结算系统通知，修改订单状态为已完成，更新商家与经纪人的累计结算分销佣金
                if (OrderStateEnum.VERIFIED.getValue().equals(orderPo.getOrderState())) {
                    LocalDateTime verifyTime = orderPo.getVerifyTime();
                    LocalDateTime verifyTimeTmp = verifyTime.plusDays(1);
                    // T+1
                    if (verifyTimeTmp.isBefore(now)) {
                        settleOrder(now, orderPo, businessMerchantVoMap, businessMap, merchantMap, agentEnterApplyDetailMap, agentUserMap);
                    }
                }
            }
        }

        return null;
    }

    private Integer getOrderSize(List<TbOrderItemPo> enrolledSuccessOrderItems) {
        Set<Long> enrolledSuccessOrderIds = enrolledSuccessOrderItems.stream().map(TbOrderItemPo::getOrderId).collect(Collectors.toSet());
        return enrolledSuccessOrderIds.size();
    }

    private void settleOrder(LocalDateTime now, TbOrderPo tbOrderPo,
                             Map<Long, BusinessMerchantVo> businessMerchantVoMap,
                             Map<Long, BusinessDetailVo> businessMap,
                             Map<Long, MerchantDetailVo> merchantMap,
                             Map<Long, List<AgentEnterApplyDetailVo>> agentEnterApplyDetailMap,
                             Map<Long, AppUserVo> agentUserMap) {
        Long id = tbOrderPo.getId();
        Long agentId = tbOrderPo.getAgentId();
        Long businessId = tbOrderPo.getBusinessId();
        // 订单收入
        BigDecimal orderIncomeAmt = tbOrderPo.getOrderIncomeAmt();
        // 商家自有商户
        Long businessMerchantId = tbOrderPo.getMerchantId();

        BusinessDetailVo businessDetailVo = businessMap.get(businessId);
        if (businessDetailVo == null) {
            return;
        }

        List<TbOrderItemPo> orderItemPoList = orderItemMapper.selectList(new QueryWrapper<TbOrderItemPo>()
                .eq("del_state", 0)
                .eq("order_id", id)
                .eq("sub_order_state", SubOrderStateEnum.VERIFIED.getValue()));
        // 如果存在未结算的子订单，则不进行父订单的结算
        if (!CollectionUtils.isEmpty(orderItemPoList)) {
            return;
        }

        // 商户本金和补贴
        Map<Long, MerchantAmtAddDto> merchantAmtAddDtoMap = new HashMap<>();
        // 佣金
        BigDecimal totalCommissionAmt = BigDecimal.ZERO;
        List<MerchantAmtBillSaveDto> merchantAmtBillSaveDtos = new ArrayList<>();
        List<CommissionBillSaveDto> commissionBillSaveDtos = new ArrayList<>();

        // 分组计算商品本金和补贴，累计佣金，和订单收入
//        for (TbOrderItemPo tbOrderItemPo : orderItemPoList) {
//            // 商品本金
//            BigDecimal merchantAmt = tbOrderItemPo.getMerchantAmt();
//            // 佣金(需要自行计算手续费,由经纪人承担)
//            BigDecimal commissionAmt = tbOrderItemPo.getCommissionAmt();
//            // 总补贴(不需要自行计算手续费,由商家承担)=订单补贴+红包金额
//            BigDecimal totalSubsidyAmt = tbOrderItemPo.getTotalSubsidyAmt();
//            BigDecimal returnAmt = tbOrderItemPo.getReturnAmt();
//            Long merchantId = tbOrderItemPo.getMerchantId();
//            String subOrderNo = tbOrderItemPo.getSubOrderNo();
//            Long orderId = tbOrderItemPo.getOrderId();
//
//            // 累加商户本金和商户补贴
//            MerchantDetailVo merchantDetailVo = merchantMap.get(merchantId);
//            if (merchantDetailVo != null) {
//                BigDecimal balanceAmt = BigDecimal.ZERO;
//                BigDecimal subsidyAmt = BigDecimal.ZERO;
//                MerchantAmtAddDto merchantAmtAddDto = merchantAmtAddDtoMap.get(merchantId);
//                if (merchantAmtAddDto != null) {
//                    BigDecimal getBalanceAmt = merchantAmtAddDto.getBalanceAmt();
//                    if (getBalanceAmt != null) {
//                        balanceAmt = getBalanceAmt;
//                    }
//
//                    BigDecimal getSubsidyAmt = merchantAmtAddDto.getSubsidyAmt();
//                    if (getSubsidyAmt != null) {
//                        subsidyAmt = getSubsidyAmt;
//                    }
//                } else {
//                    merchantAmtAddDto = new MerchantAmtAddDto();
//                    merchantAmtAddDto.setId(merchantId);
//                }
//                merchantAmtAddDto.setBalanceAmt(balanceAmt.add(merchantAmt));
//                merchantAmtAddDto.setSubsidyAmt(subsidyAmt.add(totalSubsidyAmt));
//                merchantAmtAddDtoMap.put(merchantId, merchantAmtAddDto);
//
//                BigDecimal beforeBalanceAmt = merchantDetailVo.getBalanceAmt();
//                BigDecimal beforeSubsidyAmt = merchantDetailVo.getSubsidyAmt();
//                BigDecimal afterMerchantAmt = beforeBalanceAmt.add(merchantAmt);
//                BigDecimal afterSubsidyAmt = beforeSubsidyAmt.add(totalSubsidyAmt);
//                merchantDetailVo.setBalanceAmt(afterMerchantAmt);
//                merchantDetailVo.setSubsidyAmt(afterSubsidyAmt);
//                merchantMap.put(merchantId, merchantDetailVo);
//
//                MerchantAmtBillSaveDto merchantAmtBillSaveDto = new MerchantAmtBillSaveDto();
//                merchantAmtBillSaveDto.setOrderId(orderId);
//                merchantAmtBillSaveDto.setBillNo(NoUtils.getMemberAmtBillNo());
//                merchantAmtBillSaveDto.setMerchantId(merchantId);
//                merchantAmtBillSaveDto.setBillType(BillTypeEnum.INCOME.getValue());
//                merchantAmtBillSaveDto.setTradeType(MemberAmtBillTradeTypeEnum.ORDER_AMT.getValue());
//                merchantAmtBillSaveDto.setRelationTradeNo(subOrderNo);
//                merchantAmtBillSaveDto.setBeforeAmt(beforeBalanceAmt);
//                merchantAmtBillSaveDto.setTradeAmt(merchantAmt);
//                merchantAmtBillSaveDto.setAfterAmt(afterMerchantAmt);
//                merchantAmtBillSaveDto.setTradeTime(now);
//                merchantAmtBillSaveDto.setCreateTime(now);
//                merchantAmtBillSaveDto.setUpdateTime(now);
//                merchantAmtBillSaveDtos.add(merchantAmtBillSaveDto);
//
//                merchantAmtBillSaveDto = new MerchantAmtBillSaveDto();
//                merchantAmtBillSaveDto.setOrderId(orderId);
//                merchantAmtBillSaveDto.setBillNo(NoUtils.getMemberAmtBillNo());
//                merchantAmtBillSaveDto.setMerchantId(merchantId);
//                merchantAmtBillSaveDto.setBillType(BillTypeEnum.INCOME.getValue());
//                merchantAmtBillSaveDto.setTradeType(MemberAmtBillTradeTypeEnum.ORDER_SUBSIDY.getValue());
//                merchantAmtBillSaveDto.setRelationTradeNo(subOrderNo);
//                merchantAmtBillSaveDto.setBeforeAmt(beforeSubsidyAmt);
//                merchantAmtBillSaveDto.setTradeAmt(totalSubsidyAmt);
//                merchantAmtBillSaveDto.setAfterAmt(afterSubsidyAmt);
//                merchantAmtBillSaveDto.setTradeTime(now);
//                merchantAmtBillSaveDto.setCreateTime(now);
//                merchantAmtBillSaveDto.setUpdateTime(now);
//                merchantAmtBillSaveDtos.add(merchantAmtBillSaveDto);
//            }
//
//            // 累计佣金
//            if (agentId != null && agentId > 0) {
//                AppUserVo appUserVo = agentUserMap.get(agentId);
//                if (appUserVo != null) {
//                    BigDecimal beforeCommissionAmt = appUserVo.getCommissionAmt();
//                    BigDecimal afterCommissionAmt = beforeCommissionAmt.add(commissionAmt);
//                    appUserVo.setCommissionAmt(afterCommissionAmt);
//                    agentUserMap.put(agentId, appUserVo);
//                    totalCommissionAmt = totalCommissionAmt.add(commissionAmt);
//
//                    CommissionBillSaveDto commissionBillSaveDto = new CommissionBillSaveDto();
//                    commissionBillSaveDto.setBillNo(NoUtils.getMemberAmtBillNo());
//                    commissionBillSaveDto.setUserId(agentId);
//                    commissionBillSaveDto.setBillType(BillTypeEnum.INCOME.getValue());
//                    commissionBillSaveDto.setTradeType(CommissionBillTradeTypeEnum.ORDER_COMMISSION.getValue());
//                    commissionBillSaveDto.setRelationTradeNo(subOrderNo);
//                    commissionBillSaveDto.setBeforeAmt(beforeCommissionAmt);
//                    commissionBillSaveDto.setTradeAmt(commissionAmt);
//                    commissionBillSaveDto.setAfterAmt(afterCommissionAmt);
//                    commissionBillSaveDto.setTradeTime(now);
//                    commissionBillSaveDto.setCreateTime(now);
//                    commissionBillSaveDto.setUpdateTime(now);
//                    commissionBillSaveDtos.add(commissionBillSaveDto);
//                }
//            }
//        }

        if (orderIncomeAmt.compareTo(BigDecimal.ZERO) > 0) {
            MerchantDetailVo merchantDetailVo = merchantMap.get(businessMerchantId);
            if (merchantDetailVo != null) {
                BigDecimal balanceAmt = BigDecimal.ZERO;
                MerchantAmtAddDto merchantAmtAddDto = merchantAmtAddDtoMap.get(businessMerchantId);
                if (merchantAmtAddDto != null) {
                    BigDecimal getBalanceAmt = merchantAmtAddDto.getBalanceAmt();
                    if (getBalanceAmt != null) {
                        balanceAmt = getBalanceAmt;
                    }
                } else {
                    merchantAmtAddDto = new MerchantAmtAddDto();
                    merchantAmtAddDto.setId(businessMerchantId);
                }

                merchantAmtAddDto.setBalanceAmt(balanceAmt.add(orderIncomeAmt));
                merchantAmtAddDtoMap.put(businessMerchantId, merchantAmtAddDto);

                BigDecimal beforeBalanceAmt = merchantDetailVo.getBalanceAmt();
                BigDecimal afterMerchantAmt = beforeBalanceAmt.add(orderIncomeAmt);
                merchantDetailVo.setBalanceAmt(afterMerchantAmt);
                merchantMap.put(businessMerchantId, merchantDetailVo);

                MerchantAmtBillSaveDto merchantAmtBillSaveDto = new MerchantAmtBillSaveDto();
                merchantAmtBillSaveDto.setOrderId(tbOrderPo.getId());
                merchantAmtBillSaveDto.setBillNo(NoUtils.getMemberAmtBillNo());
                merchantAmtBillSaveDto.setMerchantId(businessMerchantId);
                merchantAmtBillSaveDto.setBillType(BillTypeEnum.INCOME.getValue());
                merchantAmtBillSaveDto.setTradeType(MemberAmtBillTradeTypeEnum.ORDER_INCOME_AMT.getValue());
                merchantAmtBillSaveDto.setRelationTradeNo(tbOrderPo.getOrderNo());
                merchantAmtBillSaveDto.setBeforeAmt(beforeBalanceAmt);
                merchantAmtBillSaveDto.setTradeAmt(orderIncomeAmt);
                merchantAmtBillSaveDto.setAfterAmt(afterMerchantAmt);
                merchantAmtBillSaveDto.setTradeTime(now);
                merchantAmtBillSaveDto.setCreateTime(now);
                merchantAmtBillSaveDto.setUpdateTime(now);
                merchantAmtBillSaveDtos.add(merchantAmtBillSaveDto);
            }
        }

        List<TbOrderSettleBillPo> orderSettleBillPos = new ArrayList<>();

        // 给商户/经纪人分钱,并添加订单结算记录数据
        if (!CollectionUtils.isEmpty(merchantAmtAddDtoMap)) {
            for (Long merchantId : merchantAmtAddDtoMap.keySet()) {
                MerchantAmtAddDto merchantAmtAddDto = merchantAmtAddDtoMap.get(merchantId);
                BigDecimal balanceAmt = merchantAmtAddDto.getBalanceAmt();
                BigDecimal subsidyAmt = merchantAmtAddDto.getSubsidyAmt();

                MerchantDetailVo merchantDetailVo = merchantMap.get(merchantId);
                if (merchantDetailVo == null) {
                    continue;
                }

                if (balanceAmt != null && balanceAmt.compareTo(BigDecimal.ZERO) > 0) {
                    LocalDateTime nowLocalDateTime = LocalDateUtil.getNowLocalDateTime();
                    String yyyyMMdd = LocalDateUtil.toLocalDateToString(nowLocalDateTime.toLocalDate(), "yyyyMMdd");
                    String reqSeqId = LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime, "yyyyMMddHHmmss") + GenerateUtil.getRandomNum(5);

                    String inHfId = "";
                    String inHfAcctId = "";
                    BusinessMerchantVo businessMerchantVo = businessMerchantVoMap.get(merchantId);
                    if (businessMerchantVo == null) {
                        // 不是商家自有商户
                        inHfId = merchantDetailVo.getHfMerchantNo();
                    } else {
                        // 是商家自有商户,则需要获取现金户
                        BusinessDetailVo getBusinessDetailVo = businessMap.get(businessMerchantVo.getBusinessId());
                        if (getBusinessDetailVo != null) {
                            inHfId = getBusinessDetailVo.getHfMerchantNo();
                            inHfAcctId = getBusinessDetailVo.getHfAcctId();
                        }
                    }

                    // 结算池商户，收款账户=结算池本金账户  by much 20240410
                    if (FinancialAccountTypeEnum.PLATFORM.getValue() == merchantDetailVo.getFinancialAccountType()) {
                        inHfId = hdFinancialAccountProperties.getHfMerchantNo();
                        inHfAcctId = hdFinancialAccountProperties.getHfPrincipalAccount();
                    }

                    balanceAmt = balanceAmt.setScale(2, BigDecimal.ROUND_HALF_UP);

                    // 计算服务费
//                    // 需要自行计算手续费,由商户承担, 消费者下单，平台到账金额会扣除0.3%手续费+0.2%平台抽取，最低收取0.01元，这块由商户承担，余额支付(给商户分本金)接口不会扣除手续费
//                    BigDecimal feeAmt = balanceAmt.multiply(Constant.MERCHANT_AMT_RATE).setScale(2, BigDecimal.ROUND_HALF_UP);
//                    // 不足0.01,按0.01扣
//                    if (feeAmt.compareTo(new BigDecimal("0.01")) < 0) {
//                        feeAmt = new BigDecimal("0.01");
//                    }
//                    BigDecimal calBalanceAmt = balanceAmt.subtract(feeAmt);

                    // 2024-04-09 服务费改成支付接口扣除
                    BigDecimal feeAmt = BigDecimal.ZERO;
                    BigDecimal calBalanceAmt = balanceAmt;

                    // 添加订单结算记录
                    TbOrderSettleBillPo tbOrderSettleBillPo = new TbOrderSettleBillPo();
                    tbOrderSettleBillPo.setOrderId(id);
                    tbOrderSettleBillPo.setActiveId(tbOrderPo.getActiveId());
                    tbOrderSettleBillPo.setBusinessId(businessId);
                    tbOrderSettleBillPo.setBusinessFinancialAccountType(businessDetailVo.getFinancialAccountType());
                    tbOrderSettleBillPo.setMerchantId(merchantId);
                    tbOrderSettleBillPo.setMerchantFinancialAccountType(merchantDetailVo.getFinancialAccountType());
                    tbOrderSettleBillPo.setUserId(tbOrderPo.getUserId());
                    tbOrderSettleBillPo.setAgentId(tbOrderPo.getAgentId());
                    tbOrderSettleBillPo.setAgent2Id(tbOrderPo.getAgent2Id());
                    tbOrderSettleBillPo.setTradeType(OrderSettleBillTradeTypeEnum.MERCHANT_AMT.getValue());
                    tbOrderSettleBillPo.setTradeAmt(balanceAmt);
                    // 需要自行计算手续费
                    tbOrderSettleBillPo.setReceiveAmt(calBalanceAmt);
                    tbOrderSettleBillPo.setFeeAmt(feeAmt);
                    tbOrderSettleBillPo.setInHfId(inHfId);
                    tbOrderSettleBillPo.setInHfAcctId(inHfAcctId);
                    tbOrderSettleBillPo.setReqDate(yyyyMMdd);
                    tbOrderSettleBillPo.setReqSeqId(reqSeqId);
                    tbOrderSettleBillPo.setTradeTime(nowLocalDateTime);
                    tbOrderSettleBillPo.setCreateTime(nowLocalDateTime);
                    tbOrderSettleBillPo.setUpdateTime(nowLocalDateTime);
                    tbOrderSettleBillPo.setTradeState(OrderSettleBillTradeStateEnum.WAIT.getValue());
                    // 是否需要统计到月度结算
                    if (FinancialAccountTypeEnum.PLATFORM.getValue() == merchantDetailVo.getFinancialAccountType()) {
                        tbOrderSettleBillPo.setMonthSettleState(MonthSettleStateEnum.WAIT.getValue());
                    }

                    orderSettleBillPos.add(tbOrderSettleBillPo);
                }

                if (subsidyAmt != null && subsidyAmt.compareTo(BigDecimal.ZERO) > 0) {
                    LocalDateTime nowLocalDateTime = LocalDateUtil.getNowLocalDateTime();
                    String yyyyMMdd = LocalDateUtil.toLocalDateToString(nowLocalDateTime.toLocalDate(), "yyyyMMdd");
                    String reqSeqId = LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime, "yyyyMMddHHmmss") + GenerateUtil.getRandomNum(5);

                    // 出款帐号判断，如果商家=结算池商家，出款账户为结算池商家补贴账户  by much 20240409
                    String outHfId = businessDetailVo.getHfMerchantNo();
                    if (FinancialAccountTypeEnum.PLATFORM.getValue() == businessDetailVo.getFinancialAccountType()) {
                        outHfId = hdFinancialAccountProperties.getHfMerchantNo();
                    }

                    String inHfId = "";
                    String inHfAcctId = "";
                    BusinessMerchantVo businessMerchantVo = businessMerchantVoMap.get(merchantId);
                    if (businessMerchantVo == null) {
                        // 不是商家自有商户
                        inHfId = merchantDetailVo.getHfMerchantNo();
                    } else {
                        // 是商家自有商户,则需要获取现金户
                        BusinessDetailVo getBusinessDetailVo = businessMap.get(businessMerchantVo.getBusinessId());
                        if (getBusinessDetailVo != null) {
                            inHfId = getBusinessDetailVo.getHfMerchantNo();
                            inHfAcctId = getBusinessDetailVo.getHfAcctId();
                        }
                    }
                    // 收款账户判断，如果商户=结算池商户，收款账户为结算池补贴接收账户  by much 20240409
                    if (FinancialAccountTypeEnum.PLATFORM.getValue() == merchantDetailVo.getFinancialAccountType()) {
                        inHfId = hdFinancialAccountProperties.getHfMerchantNo();
                        inHfAcctId = hdFinancialAccountProperties.getHfSubsidyInboundAccount();
                    }

                    subsidyAmt = subsidyAmt.setScale(2, BigDecimal.ROUND_DOWN);

                    // 添加订单结算记录
                    TbOrderSettleBillPo tbOrderSettleBillPo = new TbOrderSettleBillPo();
                    tbOrderSettleBillPo.setOrderId(id);
                    tbOrderSettleBillPo.setActiveId(tbOrderPo.getActiveId());
                    tbOrderSettleBillPo.setBusinessId(businessId);
                    tbOrderSettleBillPo.setBusinessFinancialAccountType(businessDetailVo.getFinancialAccountType());
                    tbOrderSettleBillPo.setMerchantId(merchantId);
                    tbOrderSettleBillPo.setMerchantFinancialAccountType(merchantDetailVo.getFinancialAccountType());
                    tbOrderSettleBillPo.setUserId(tbOrderPo.getUserId());
                    tbOrderSettleBillPo.setAgentId(tbOrderPo.getAgentId());
                    tbOrderSettleBillPo.setTradeType(OrderSettleBillTradeTypeEnum.SUBSIDY_AMT.getValue());
                    tbOrderSettleBillPo.setTradeAmt(subsidyAmt);
                    tbOrderSettleBillPo.setFeeAmt(BigDecimal.ZERO);
                    tbOrderSettleBillPo.setReceiveAmt(subsidyAmt);
                    tbOrderSettleBillPo.setOutHfId(outHfId);
                    tbOrderSettleBillPo.setInHfId(inHfId);
                    tbOrderSettleBillPo.setInHfAcctId(inHfAcctId);
                    tbOrderSettleBillPo.setReqDate(yyyyMMdd);
                    tbOrderSettleBillPo.setReqSeqId(reqSeqId);
                    tbOrderSettleBillPo.setTradeTime(nowLocalDateTime);
                    tbOrderSettleBillPo.setCreateTime(nowLocalDateTime);
                    tbOrderSettleBillPo.setUpdateTime(nowLocalDateTime);
                    tbOrderSettleBillPo.setTradeState(OrderSettleBillTradeStateEnum.WAIT.getValue());
                    tbOrderSettleBillPo.setMonthSettleState(MonthSettleStateEnum.WAIT.getValue());

                    orderSettleBillPos.add(tbOrderSettleBillPo);
                }
            }
        }

        // 分佣金 移到子订单结算去了
//        if (agentId != null && agentId > 0 && totalCommissionAmt.compareTo(BigDecimal.ZERO) > 0) {
//            // 计算扣除手续费后的佣金      7.5%的手续费，不做四舍五入，去掉第三位
//            BigDecimal calTotalCommissionAmt = totalCommissionAmt.divide(Constant.AGENT_AMT_RATE, 2, BigDecimal.ROUND_DOWN);
//            BigDecimal feeAmt = totalCommissionAmt.subtract(calTotalCommissionAmt);
//
//            LocalDateTime nowLocalDateTime = LocalDateUtil.getNowLocalDateTime();
//            String yyyyMMdd = LocalDateUtil.toLocalDateToString(nowLocalDateTime.toLocalDate(), "yyyyMMdd");
//            String reqSeqId = LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime, "yyyyMMddHHmmss") + GenerateUtil.getRandomNum(5);
//
//            String inHfId = "";
//            String outHfId = "";
//
//            // 查询经纪人是否已签约成功，如果未签约，则记录到表，不调用hf接口
//            List<AgentEnterApplyDetailVo> agentEnterApplyDetailVos = agentEnterApplyDetailMap.get(agentId);
//            if (!CollectionUtils.isEmpty(agentEnterApplyDetailVos)) {
//                AgentEnterApplyDetailVo agentEnterApplyDetailVo = agentEnterApplyDetailVos.get(0);
//                inHfId = agentEnterApplyDetailVo.getHfId();
//            }
//
//            // 添加订单结算记录
//            TbOrderSettleBillPo tbOrderSettleBillPo = new TbOrderSettleBillPo();
//            tbOrderSettleBillPo.setOrderId(id);
//            tbOrderSettleBillPo.setActiveId(tbOrderPo.getActiveId());
//            tbOrderSettleBillPo.setBusinessId(businessId);
//            tbOrderSettleBillPo.setMerchantId(0L);
//            tbOrderSettleBillPo.setUserId(tbOrderPo.getUserId());
//            tbOrderSettleBillPo.setAgentId(tbOrderPo.getAgentId());
//            tbOrderSettleBillPo.setTradeType(OrderSettleBillTradeTypeEnum.COMMISSION_AMT.getValue());
//            tbOrderSettleBillPo.setTradeAmt(totalCommissionAmt);
//            // 需要自行计算手续费
//            tbOrderSettleBillPo.setReceiveAmt(calTotalCommissionAmt);
//            tbOrderSettleBillPo.setFeeAmt(feeAmt);
//            tbOrderSettleBillPo.setOutHfId(outHfId);
//            tbOrderSettleBillPo.setInHfId(inHfId);
//            tbOrderSettleBillPo.setInHfAcctId("");
//            tbOrderSettleBillPo.setReqDate(yyyyMMdd);
//            tbOrderSettleBillPo.setReqSeqId(reqSeqId);
//            tbOrderSettleBillPo.setTradeTime(nowLocalDateTime);
//            tbOrderSettleBillPo.setCreateTime(nowLocalDateTime);
//            tbOrderSettleBillPo.setUpdateTime(nowLocalDateTime);
//            tbOrderSettleBillPo.setTradeState(OrderSettleBillTradeStateEnum.WAIT.getValue());
//
//            orderSettleBillPos.add(tbOrderSettleBillPo);
//        }

        // 统计商家与经纪人的累计结算分销佣金 移到子订单结算去了
//        UpdateBusinessAgentOrderDto updateBusinessAgentOrderDto = new UpdateBusinessAgentOrderDto();
//        updateBusinessAgentOrderDto.setBusinessId(businessId);
//        updateBusinessAgentOrderDto.setUserId(agentId);
//        updateBusinessAgentOrderDto.setTotalSettleCommission(totalCommissionAmt);

        // 生成商户的订单账单明细
        Map<String, List<TbOrderSettleBillItemPo>> orderSettleBillItemsMap = getOrderSettleBillItemsMap(businessId, merchantAmtBillSaveDtos);

        TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

        try {
            // 1、修改订单状态，已核销-》已完成
            OrderStateUpdateParam orderStateUpdateParam = new OrderStateUpdateParam();
            orderStateUpdateParam.setId(tbOrderPo.getId());
            orderStateUpdateParam.setOrgOrderState(OrderStateEnum.VERIFIED.getValue());
            orderStateUpdateParam.setOrderState(OrderStateEnum.FINISH.getValue());
            orderStateUpdateParam.setFinishTime(now);
            int update = baseMapper.updateOrderState(orderStateUpdateParam);
            if (update == 0) {
                log.error("更新主订单状态失败，orderId：{}", id);
                Throw.isBusinessException("更新主订单状态失败");
            }

            // 2、添加订单结算记录数据（商户本金/商户补贴/经纪人佣金）待支付
            for (TbOrderSettleBillPo orderSettleBillPo : orderSettleBillPos) {
                int insert = orderSettleBillMapper.insert(orderSettleBillPo);
                if (insert == 0) {
                    log.error("添加订单结算记录数据失败，orderId：{}", id);
                    Throw.isBusinessException("添加订单结算记录数据失败");
                }
                // 本金or补贴明细
                String key = orderSettleBillPo.getMerchantId() + "&" + orderSettleBillPo.getTradeType();
                List<TbOrderSettleBillItemPo> tbOrderSettleBillItemPos = orderSettleBillItemsMap.get(key);
                if (!CollectionUtils.isEmpty(tbOrderSettleBillItemPos)) {
                    tbOrderSettleBillItemPos.forEach(e -> e.setBillId(orderSettleBillPo.getId()));
                    orderSettleBillItemService.saveBatch(tbOrderSettleBillItemPos);
                }
            }

            // 3、更新商户本金，商户补贴和经纪人佣金，添加商户资金流水和经纪人佣金流水，统计商家与经纪人的累计结算分销佣金
            OrderSettleUpdateDto orderSettleUpdateDto = new OrderSettleUpdateDto();
            orderSettleUpdateDto.setOrderId(id);
            orderSettleUpdateDto.setAgentId(agentId);
            orderSettleUpdateDto.setMerchantAmtAdds(filterMerchantAmtAddDtos(merchantMap, merchantAmtAddDtoMap.values()));
            orderSettleUpdateDto.setCommissionAmt(totalCommissionAmt);
            orderSettleUpdateDto.setMerchantAmtBillSaves(filterMerchantAmtBill(merchantMap, merchantAmtBillSaveDtos));
            orderSettleUpdateDto.setCommissionBillSaves(commissionBillSaveDtos);
//            orderSettleUpdateDto.setUpdateBusinessAgentOrderDto(updateBusinessAgentOrderDto);
            // 普通商户的本金需要自动提现
            orderSettleUpdateDto.setAutoWithdrawalRecords(generateAutoWithdrawalRecords(orderSettleBillPos));
            Boolean updateOrderSettleAmtState = appUserApi.updateOrderSettleAmt(orderSettleUpdateDto).unpack();
            if (updateOrderSettleAmtState == null || !updateOrderSettleAmtState) {
                log.error("更新订单结算金额失败，orderId：{}", id);
                Throw.isBusinessException("更新订单结算金额失败");
            }

            transactionManager.commit(transaction);
        } catch (Exception e) {
            //回滚事务
            transactionManager.rollback(transaction);
            log.error("<订单结算>事务异常回滚", e);
            Throw.isBusinessException(e.getMessage());
        }

        // 4、根据第三方交易状态，更新订单结算记录状态；
        //     如果出现更新状态失败，但资金已经处理成功，在提现时候做查单处理，reqDate和reqSeqId在添加订单结算记录时设置了
        //  给商户付本金（调用第三方）
        //  给商户付补贴（调用第三方） 2024-04-26 废弃，补贴不走这里了，使用 businessApi.scanSubsidyWaitPayJob() 进行补贴金扣减及汇付转账
        //  给经纪人付佣金（调用第三方）
        hfSettlePay(orderSettleBillPos);

        // 5、给商户发送结算系统通知
        if (!CollectionUtils.isEmpty(merchantAmtBillSaveDtos)) {
            Map<String, List<MerchantAmtBillSaveDto>> merchantAmtBillMap = merchantAmtBillSaveDtos.stream().filter(merchantAmtBillSaveDto ->
                    !MemberAmtBillTradeTypeEnum.ORDER_INCOME_AMT.getValue().equals(merchantAmtBillSaveDto.getTradeType()))
                    .collect(Collectors.groupingBy(MerchantAmtBillSaveDto::getRelationTradeNo));

            for (String subOrderNo : merchantAmtBillMap.keySet()) {
                BigDecimal merchantAmt = BigDecimal.ZERO;
                BigDecimal merchantSubsidyAmt = BigDecimal.ZERO;
                List<MerchantAmtBillSaveDto> merchantAmtBillSaveDtoList = merchantAmtBillMap.get(subOrderNo);
                for (MerchantAmtBillSaveDto merchantAmtBillSaveDto : merchantAmtBillSaveDtoList) {
                    BigDecimal tradeAmt = merchantAmtBillSaveDto.getTradeAmt();
                    Integer tradeType = merchantAmtBillSaveDto.getTradeType();
                    if (MemberAmtBillTradeTypeEnum.ORDER_AMT.getValue().equals(tradeType)) {
                        merchantAmt = merchantAmt.add(tradeAmt);
                    } else if (MemberAmtBillTradeTypeEnum.ORDER_SUBSIDY.getValue().equals(tradeType)) {
                        merchantSubsidyAmt = merchantSubsidyAmt.add(tradeAmt);
                    }
                }

                MerchantAmtBillSaveDto merchantAmtBillSaveDto = merchantAmtBillSaveDtoList.get(0);

                // 发送订单结算系统通知
                NotifyMsgSendDto notifyMsgSendDto = new NotifyMsgSendDto();
                notifyMsgSendDto.setUserId(merchantAmtBillSaveDto.getMerchantId());
                notifyMsgSendDto.setRoleType(RoleTypeEnum.MERCHANT.getValue());
                notifyMsgSendDto.setMsgType(NotifyMsgTypeEnum.MERCHANT_ORDER_SETTLE.getValue());
                notifyMsgSendDto.setContent(String.format(MsgConstant.MERCHANT_ORDER_SETTLE, subOrderNo,
                        merchantAmt,
                        merchantSubsidyAmt));
                notifyMsgSendDto.setMsgState(NotifyMsgStateEnum.NO_READ.getValue());
                notifyMsgProvider.sendMsg(notifyMsgSendDto);
            }
        }

    }

    /**
     * 普通商户的本金，需要自动提现
     */
    private List<AutoWithdrawalRecordDto> generateAutoWithdrawalRecords(List<TbOrderSettleBillPo> orderSettleBills) {
        if (CollectionUtils.isEmpty(orderSettleBills)) {
            return Collections.emptyList();
        }
        return orderSettleBills.stream()
                // 商户本金 & 商户资金账户=自建账户
                .filter(e -> OrderSettleBillTradeTypeEnum.MERCHANT_AMT.getValue().equals(e.getTradeType())
                        && e.getMerchantFinancialAccountType() != null
                        && e.getMerchantFinancialAccountType() == FinancialAccountTypeEnum.SELF.getValue())
                .map(e -> {
                    AutoWithdrawalRecordDto autoWithdrawalRecordDto = new AutoWithdrawalRecordDto();
                    autoWithdrawalRecordDto.setBillId(e.getId());
                    autoWithdrawalRecordDto.setOrderId(e.getOrderId());
                    autoWithdrawalRecordDto.setBusinessId(e.getBusinessId());
                    autoWithdrawalRecordDto.setMerchantId(e.getMerchantId());
                    autoWithdrawalRecordDto.setWithdrawalAmt(e.getTradeAmt());
                    autoWithdrawalRecordDto.setState(AutoWithdrawalStateEnum.WAIT.getValue());
                    return autoWithdrawalRecordDto;
                })
                .collect(Collectors.toList());
    }

    /**
     * 生成商户的订单账单明细
     *
     * @param merchantAmtBillSaveDtoList 商户资金流水
     * @return key: merchant_id&trade_type, value: 订单账单明细
     */
    private Map<String, List<TbOrderSettleBillItemPo>> getOrderSettleBillItemsMap(Long businessId, List<MerchantAmtBillSaveDto> merchantAmtBillSaveDtoList) {
        if (CollectionUtils.isEmpty(merchantAmtBillSaveDtoList)) {
            return Collections.emptyMap();
        }
        return merchantAmtBillSaveDtoList.stream()
                .filter(e -> MemberAmtBillTradeTypeEnum.ORDER_AMT.getValue().equals(e.getTradeType())
                        || MemberAmtBillTradeTypeEnum.ORDER_SUBSIDY.getValue().equals(e.getTradeType()))
                .map(e -> {
                    TbOrderSettleBillItemPo tbOrderSettleBillItemPo = BeanUtil.copyProperties(e, TbOrderSettleBillItemPo.class);
                    tbOrderSettleBillItemPo.setBusinessId(businessId);
                    tbOrderSettleBillItemPo.setSubOrderNo(e.getRelationTradeNo());
                    if (MemberAmtBillTradeTypeEnum.ORDER_AMT.getValue().equals(e.getTradeType())) {
                        tbOrderSettleBillItemPo.setTradeType(OrderSettleBillTradeTypeEnum.MERCHANT_AMT.getValue());
                    } else if (MemberAmtBillTradeTypeEnum.ORDER_SUBSIDY.getValue().equals(e.getTradeType())) {
                        tbOrderSettleBillItemPo.setTradeType(OrderSettleBillTradeTypeEnum.SUBSIDY_AMT.getValue());
                    }
                    return tbOrderSettleBillItemPo;
                }).collect(Collectors.groupingBy(e -> e.getMerchantId() + "&" + e.getTradeType()));
    }

    /**
     * 剔除商户补贴资金明细 and 结算池商户本金资金明细
     *
     * @param merchantAmtBillSaveDtoList 商户资金明细
     * @return 剔除了商户补贴的资金明细
     */
    private List<MerchantAmtBillSaveDto> filterMerchantAmtBill(Map<Long, MerchantDetailVo> merchantMap, List<MerchantAmtBillSaveDto> merchantAmtBillSaveDtoList) {
        if (CollectionUtils.isEmpty(merchantAmtBillSaveDtoList)) {
            return Collections.emptyList();
        }
        return merchantAmtBillSaveDtoList.stream()
                .filter(e -> {
                    if (MemberAmtBillTradeTypeEnum.ORDER_SUBSIDY.getValue().equals(e.getTradeType())) {
                        return false;
                    }
                    MerchantDetailVo merchantDetailVo = merchantMap.get(e.getMerchantId());
                    if (FinancialAccountTypeEnum.PLATFORM.getValue() == merchantDetailVo.getFinancialAccountType()
                            && MemberAmtBillTradeTypeEnum.ORDER_AMT.getValue().equals(e.getTradeType())) {
                        return false;
                    }
                    return true;
                })
                .collect(Collectors.toList());
    }

    /**
     * 过滤掉商户补贴，商户补贴在次月才结算
     *
     * @return 商户本金增加记录
     */
    private List<MerchantAmtAddDto> filterMerchantAmtAddDtos(Map<Long, MerchantDetailVo> merchantMap, Collection<MerchantAmtAddDto> merchantAmtAddList) {
        if (CollectionUtils.isEmpty(merchantAmtAddList)) {
            return Collections.emptyList();
        }
        merchantAmtAddList.forEach(e -> {
            // 补贴在月度结算时增加
            e.setSubsidyAmt(BigDecimal.ZERO);
            // 结算池商户本金在结算后次日到账，see com.cq.hd.order.processor.settle.MerchantAmtDailySettleProcessor
            MerchantDetailVo merchantDetailVo = merchantMap.get(e.getId());
            if (FinancialAccountTypeEnum.PLATFORM.getValue() == merchantDetailVo.getFinancialAccountType()) {
                e.setBalanceAmt(BigDecimal.ZERO);
            }
        });
        return new ArrayList<>(merchantAmtAddList);
    }

    private void hfSettlePay(List<TbOrderSettleBillPo> orderSettleBillPos) {
        if (!CollectionUtils.isEmpty(orderSettleBillPos)) {
            for (TbOrderSettleBillPo orderSettleBillPo : orderSettleBillPos) {
                if (orderSettleBillPo.getTradeAmt().compareTo(BigDecimal.ZERO) <= 0) {
                    continue;
                }

                // 如果是补贴，则不在这里结算，使用 businessApi.scanSubsidyWaitPayJob() 进行结算
                if (OrderSettleBillTradeTypeEnum.SUBSIDY_AMT.getValue().equals(orderSettleBillPo.getTradeType())) {
                    continue;
                }

                OrderSettleBillVo orderSettleBillVo = new OrderSettleBillVo();
                BeanUtils.copyProperties(orderSettleBillPo, orderSettleBillVo);
                if (!OrderSettleBillFactory.getOrderSelectHandler(orderSettleBillPo.getTradeType()).transactAmt(orderSettleBillVo)) {
                    log.error("hfSettlePay处理失败，orderSettleBillId：{}", orderSettleBillPo.getId());
                }
            }
        }
    }

    @Override
    public Boolean scanOrderSettleBill() {
        List<TbOrderSettleBillPo> tbOrderSettleBillPos = orderSettleBillMapper.selectList(new QueryWrapper<TbOrderSettleBillPo>().eq("del_state", 0)
                .eq("trade_state", OrderSettleBillTradeStateEnum.PROCESSING.getValue()));
        if (CollectionUtils.isEmpty(tbOrderSettleBillPos)) {
            return true;
        }

        for (TbOrderSettleBillPo tbOrderSettleBillPo : tbOrderSettleBillPos) {
            OrderSettleBillVo orderSettleBillVo = new OrderSettleBillVo();
            BeanUtils.copyProperties(tbOrderSettleBillPo, orderSettleBillVo);
            if (!OrderSettleBillFactory.getOrderSelectHandler(tbOrderSettleBillPo.getTradeType()).transactAmt(orderSettleBillVo)) {
                log.error("scanOrderSettleBill处理失败，orderSettleBillId：{}", tbOrderSettleBillPo.getId());
            }
        }

        return true;
    }

    // todo 商户本机手续费处理完成之后要删掉
    @Override
    public Boolean generateOrderSettleBillFeeTemp() {
        List<TbOrderSettleBillPo> tbOrderSettleBillPos = orderSettleBillMapper.selectList(new QueryWrapper<TbOrderSettleBillPo>().eq("del_state", 0)
                .eq("trade_state", OrderSettleBillTradeStateEnum.SUCCESS.getValue()) // 转账成功
                .eq("trade_type", OrderSettleBillTradeTypeEnum.MERCHANT_AMT.getValue()) // 商户本金
                .gt("fee_amt", BigDecimal.ZERO) // 手续费大于0
        );
        if (CollectionUtils.isEmpty(tbOrderSettleBillPos)) {
            return true;
        }

        for (TbOrderSettleBillPo tbOrderSettleBillPo : tbOrderSettleBillPos) {
            List<TbOrderSettleBillFeeTempPo> tbOrderSettleBillFeeTempPos = orderSettleBillFeeTempMapper.selectList(new QueryWrapper<TbOrderSettleBillFeeTempPo>().eq("del_state", 0)
                    .eq("order_settle_bill_id", tbOrderSettleBillPo.getId()));
            if (!CollectionUtils.isEmpty(tbOrderSettleBillFeeTempPos)) {
                continue;
            }

            TbOrderSettleBillFeeTempPo tbOrderSettleBillFeeTempPo = new TbOrderSettleBillFeeTempPo();
            tbOrderSettleBillFeeTempPo.setOrderSettleBillId(tbOrderSettleBillPo.getId());
            tbOrderSettleBillFeeTempPo.setTradeType(tbOrderSettleBillPo.getTradeType());
            tbOrderSettleBillFeeTempPo.setTradeState(OrderSettleBillTradeStateEnum.WAIT.getValue());
            tbOrderSettleBillFeeTempPo.setFeeAmt(tbOrderSettleBillPo.getFeeAmt());
            tbOrderSettleBillFeeTempPo.setInHfId(tbOrderSettleBillPo.getInHfId());
            tbOrderSettleBillFeeTempPo.setInHfAcctId(tbOrderSettleBillPo.getInHfAcctId());
            orderSettleBillFeeTempMapper.insert(tbOrderSettleBillFeeTempPo);
        }

        return true;
    }

    // todo 商户本机手续费处理完成之后要删掉
    @Override
    public Boolean scanOrderSettleBillFeeTemp() {
        List<TbOrderSettleBillFeeTempPo> tbOrderSettleBillFeeTempPos = orderSettleBillFeeTempMapper.selectList(new QueryWrapper<TbOrderSettleBillFeeTempPo>().eq("del_state", 0)
                .eq("trade_state", OrderSettleBillTradeStateEnum.WAIT.getValue()) // 待转账
                .eq("trade_type", OrderSettleBillTradeTypeEnum.MERCHANT_AMT.getValue()) // 商户本金
                .gt("fee_amt", BigDecimal.ZERO) // 手续费大于0
        );
        if (CollectionUtils.isEmpty(tbOrderSettleBillFeeTempPos)) {
            return true;
        }

        for (TbOrderSettleBillFeeTempPo tbOrderSettleBillFeeTempPo : tbOrderSettleBillFeeTempPos) {
            OrderSettleBillFeeTempVo orderSettleBillFeeTempVo = new OrderSettleBillFeeTempVo();
            BeanUtils.copyProperties(tbOrderSettleBillFeeTempPo, orderSettleBillFeeTempVo);
            Boolean res = transactFeeAmt(orderSettleBillFeeTempVo);
            if (res) {
                log.info("订单结算商品本金手续费已处理成功，orderSettleBillId：{}", orderSettleBillFeeTempVo.getOrderSettleBillId());
            } else {
                log.info("订单结算商品本金手续费已处理失败，orderSettleBillId：{}", orderSettleBillFeeTempVo.getOrderSettleBillId());
            }
        }

        return true;
    }

    // todo 商户本机手续费处理完成之后要删掉
    private Boolean transactFeeAmt(OrderSettleBillFeeTempVo orderSettleBillFeeTempVo) {
        Long id = orderSettleBillFeeTempVo.getId();

        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "transactMerchantFeeAmt:" + id);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            TbOrderSettleBillFeeTempPo tbOrderSettleBillFeeTempPo = orderSettleBillFeeTempMapper.selectById(id);
            if (OrderSettleBillTradeStateEnum.SUCCESS.getValue().equals(tbOrderSettleBillFeeTempPo.getTradeState())) {
                log.info("订单结算商品本金手续费已处理成功，orderSettleBillFeeTempId：{}", id);
                return true;
            }

            // 根据reqData和reqSeqId调用余额支付查询接口做查单，如果已经支付成功则修改状态=支付成功
            LocalDateTime nowLocalDateTime = LocalDateUtil.getNowLocalDateTime();
            String yyyyMMdd = LocalDateUtil.toLocalDateToString(nowLocalDateTime.toLocalDate(), "yyyyMMdd");
            String reqSeqId = LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime, "yyyyMMddHHmmss") + GenerateUtil.getRandomNum(5);

            HfTradeAccountPay hfTradeAccountPay = new HfTradeAccountPay();
            hfTradeAccountPay.setReqDate(yyyyMMdd);
            hfTradeAccountPay.setReqSeqId(reqSeqId);
            hfTradeAccountPay.setOrgReqDate(orderSettleBillFeeTempVo.getReqDate());
            hfTradeAccountPay.setOrgReqSeqId(orderSettleBillFeeTempVo.getReqSeqId());
            JSONObject queryJSONObject = hfApi.tradeAccountAmtQuery(hfTradeAccountPay).unpack();
            if (queryJSONObject != null) {
                JSONObject data = queryJSONObject.getJSONObject("data");
                String respCode = data.getString("resp_code");
                if ("00000000".equals(respCode)) {
                    // 交易状态 P:处理中；S：成功；F：失败
                    String transStat = data.getString("trans_stat");

                    if ("S".equals(transStat)) {
                        orderSettleBillFeeTempVo.setTradeState(OrderSettleBillTradeStateEnum.SUCCESS.getValue());
                    } else if ("P".equals(transStat)) {
                        orderSettleBillFeeTempVo.setTradeState(OrderSettleBillTradeStateEnum.PROCESSING.getValue());
                    } else if ("F".equals(transStat)) {
                        orderSettleBillFeeTempVo.setTradeState(OrderSettleBillTradeStateEnum.FAIL.getValue());
                        orderSettleBillFeeTempVo.setTradeFailReason(JSON.toJSONString(data));
                    } else {
                        orderSettleBillFeeTempVo.setTradeFailReason(JSON.toJSONString(data));
                    }

                    // 如果不是失败，更新一下状态后直接返回
                    if (!OrderSettleBillTradeStateEnum.FAIL.getValue().equals(orderSettleBillFeeTempVo.getTradeState())) {
                        int update = orderSettleBillFeeTempMapper.updateOrderSettleBillFeeTemp(orderSettleBillFeeTempVo);
                        if (update == 0) {
                            log.error("更新订单结算商户本金手续费支付流水记录状态失败，orderSettleBillFeeTempId：{}", orderSettleBillFeeTempVo.getId());
                            return false;
                        }

                        return true;
                    }
                }
            }

            // 调用余额支付的标准接口（给商户分本金手续费）
            hfTradeAccountPay = new HfTradeAccountPay();
            String yyyyMMdd2 = LocalDateUtil.toLocalDateToString(nowLocalDateTime.toLocalDate(), "yyyyMMdd");
            String reqSeqId2 = LocalDateUtil.toLocalDateTimeToString(nowLocalDateTime, "yyyyMMddHHmmss") + GenerateUtil.getRandomNum(5);
            orderSettleBillFeeTempVo.setReqDate(yyyyMMdd2);
            orderSettleBillFeeTempVo.setReqSeqId(reqSeqId2);
            hfTradeAccountPay.setReqDate(orderSettleBillFeeTempVo.getReqDate());
            hfTradeAccountPay.setReqSeqId(orderSettleBillFeeTempVo.getReqSeqId());
            hfTradeAccountPay.setInHfId(orderSettleBillFeeTempVo.getInHfId());
            hfTradeAccountPay.setInHfAcctId(orderSettleBillFeeTempVo.getInHfAcctId());
            hfTradeAccountPay.setGoodsDesc("给商户支付商品本金");
            hfTradeAccountPay.setTransAmt(orderSettleBillFeeTempVo.getFeeAmt().toString());
            JSONObject jsonObject = hfApi.tradeAccountAmtPay(hfTradeAccountPay).unpack();
            if (jsonObject != null) {
                JSONObject data = jsonObject.getJSONObject("data");
                // 交易状态 P:处理中；S：成功；F：失败
                String transStat = data.getString("trans_stat");

                if ("S".equals(transStat)) {
                    orderSettleBillFeeTempVo.setTradeState(OrderSettleBillTradeStateEnum.SUCCESS.getValue());
                } else if ("P".equals(transStat)) {
                    orderSettleBillFeeTempVo.setTradeState(OrderSettleBillTradeStateEnum.PROCESSING.getValue());
                } else if ("F".equals(transStat)) {
                    orderSettleBillFeeTempVo.setTradeState(OrderSettleBillTradeStateEnum.FAIL.getValue());
                    orderSettleBillFeeTempVo.setTradeFailReason(JSON.toJSONString(data));
                } else {
                    orderSettleBillFeeTempVo.setTradeFailReason(JSON.toJSONString(data));
                }

                // 在提现时必须要做查单处理
                int update = orderSettleBillFeeTempMapper.updateOrderSettleBillFeeTemp(orderSettleBillFeeTempVo);
                if (update == 0) {
                    log.error("更新订单结算商户本金手续费支付流水记录状态失败，orderSettleBillFeeTempId：{}", orderSettleBillFeeTempVo.getId());
                    return false;
                }
            }

            return true;
        } finally {
            LockUtils.unlock(lockKey);
        }
    }

    /**
     * 根据提现单id，获取对应订单列表
     * @param withdrawalId
     * @return
     */
    @Override
    public List<AdminOrderPageVo> listOrderByWithdrawalId(Long withdrawalId) {
        List<MonthSettleBillVo> monthSettleBillVos = monthSettleBillWithdrawalApi.listByWithdrawalId(withdrawalId).unpack();
        if (CollectionUtils.isEmpty(monthSettleBillVos)) {
            return Collections.emptyList();
        }

        List<Long> monthSettleIds = monthSettleBillVos.stream()
                .map(MonthSettleBillVo::getId)
                .distinct()
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(monthSettleIds)) {
            return Collections.emptyList();
        }

        List<Long> orderIds = orderSettleBillMapper.getOrderIdsByMonthSettleIds(monthSettleIds);
        if (CollectionUtils.isEmpty(orderIds)) {
            return Collections.emptyList();
        }

        AdminOrderPageDto adminOrderPageDto = new AdminOrderPageDto();
        adminOrderPageDto.setOrderIds(orderIds);
        return listAdminOrder(adminOrderPageDto);
    }

    // 分销排行榜
    @Override
    public ActiveAgentRankVo agentRank(Long activeId) {
        ActiveAgentRankVo activeAgentRankVo = new ActiveAgentRankVo();
        activeAgentRankVo.setId(activeId);
        ActiveRankQueryDto activeRankQueryDto = new ActiveRankQueryDto();
        activeRankQueryDto.setActiveId(activeId);
        List<AgentRankItemVo> list = baseMapper.getAgentRank(activeRankQueryDto);
        if (CollectionUtils.isEmpty(list)) {
            return activeAgentRankVo;
        }

        List<Long> agentIds = list.stream()
                .map(AgentRankItemVo::getAgentId)
                .distinct()
                .collect(Collectors.toList());
        AgentActiveCommissionParam param = new AgentActiveCommissionParam();
        param.setActiveId(activeId);
        param.setAgentIds(agentIds);
        param.setSubOrderStates(Collections.singletonList(SubOrderStateEnum.SETTLED.getValue()));
        List<AgentRankItemVo> commissionList = orderItemMapper.getAgentActiveCommission(param);
        Map<Long, BigDecimal> agentCommissionMap = commissionList.stream()
                .collect(Collectors.toMap(AgentRankItemVo::getAgentId, AgentRankItemVo::getCommission));

        Integer totalOrderNum = 0;
        BigDecimal totalOrderPrice = BigDecimal.ZERO;
        BigDecimal totalCommission = BigDecimal.ZERO;
        for (AgentRankItemVo vo : list) {
            totalOrderNum += vo.getOrderNum();
            totalOrderPrice = totalOrderPrice.add(vo.getOrderPrice());
            BigDecimal commission = agentCommissionMap.get(vo.getAgentId());
            if (commission != null && commission.compareTo(BigDecimal.ZERO) > 0) {
                vo.setCommission(commission);
                totalCommission = totalCommission.add(commission);
            }

            // 对手机号脱敏
            vo.setMobile(PrivacyUtil.encryptMobile(vo.getMobile()));
        }
        activeAgentRankVo.setTotalOrderNum(totalOrderNum);
        activeAgentRankVo.setTotalOrderPrice(totalOrderPrice);
        activeAgentRankVo.setTotalCommission(totalCommission);

        activeAgentRankVo.setList(list);

        return activeAgentRankVo;
    }

    @Override
    public Page<AgentRankItemVo> pageAgentRank(ActiveRankQueryDto activeRankQueryDto) {
        List<AgentRankItemVo> list = baseMapper.getAgentRank(activeRankQueryDto);
        if (CollectionUtils.isEmpty(list)) {
            return Page.newPageWithAllFields(
                    Collections.emptyList(), activeRankQueryDto.getPageNum(), activeRankQueryDto.getPageSize(), 0, 0);
        }

        List<Long> agentIds = list.stream().map(AgentRankItemVo::getAgentId)
                .distinct().collect(Collectors.toList());

        // 预估佣金
        List<Integer> estimateStates = Arrays.asList(
                SubOrderStateEnum.WAIT_VERIFY.getValue(), SubOrderStateEnum.VERIFIED.getValue(), SubOrderStateEnum.SETTLED.getValue());
        Map<Long, BigDecimal> estimateCommissionMap = getAgentCommissionMap(activeRankQueryDto.getActiveId(), agentIds, estimateStates);

        // 已结算佣金
        List<Integer> settledStates = Collections.singletonList(SubOrderStateEnum.SETTLED.getValue());
        Map<Long, BigDecimal> settledCommissionMap = getAgentCommissionMap(activeRankQueryDto.getActiveId(), agentIds, settledStates);

        for (AgentRankItemVo vo : list) {
            BigDecimal estimateCommission = estimateCommissionMap.getOrDefault(vo.getAgentId(), BigDecimal.ZERO);
            vo.setEstimateCommission(estimateCommission);
            BigDecimal settledCommission = settledCommissionMap.getOrDefault(vo.getAgentId(), BigDecimal.ZERO);
            vo.setCommission(settledCommission);
        }

        // 计算排行
        for (int i=0; i<list.size(); i++) {
            list.get(i).setIndex((i + 1) + (activeRankQueryDto.getPageNum() - 1) * activeRankQueryDto.getPageSize());
        }

        PageInfo<AgentRankItemVo> pageInfo = new PageInfo<>(list);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    // 查询agent的佣金统计
    private Map<Long, BigDecimal> getAgentCommissionMap(Long activeId, List<Long> agentIds, List<Integer> subOrderStates) {
        AgentActiveCommissionParam param = new AgentActiveCommissionParam();
        param.setActiveId(activeId);
        param.setAgentIds(agentIds);
        param.setSubOrderStates(subOrderStates);
        List<AgentRankItemVo> commissionList = orderItemMapper.getAgentActiveCommission(param);
        return commissionList.stream()
                .collect(Collectors.toMap(AgentRankItemVo::getAgentId, AgentRankItemVo::getCommission));
    }

    // 活动结束
    @Override
    public void onActiveEnd(Long activeId) {
        // 未满自动退
        try {
            orderRefundService.noFullAutoRefund(activeId);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        // 阶梯价返现
        try {
            orderRefundService.calculateStepPriceRefund(activeId);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        // 固定人数满员通知
        try {
            fixedEnrollNumFullNotify(activeId);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public MerchantOrderStatisticsVo getMerchantOrderStatistics(MerchantOrderPageDto merchantOrderPageDto) {
        return orderItemMapper.statisticsMerchantOrder(merchantOrderPageDto);
    }

    @Override
    public OrderEstimateCommissionVo getOrderEstimateCommission(Long agentId) {
        LocalDate nowLocalDate = LocalDate.now();
        // 今日预估
        LocalDateTime todayStart = LocalDateUtil.toLocalDateTime(LocalDateUtil.toLocalDateToString(nowLocalDate, Constant.YYYY_MM_DD) + " 00:00:00",
                Constant.YYYY_MM_DD_HH_MM_SS);
        LocalDateTime todayEnd = LocalDateUtil.toLocalDateTime(LocalDateUtil.toLocalDateToString(nowLocalDate, Constant.YYYY_MM_DD) + " 23:59:59",
                Constant.YYYY_MM_DD_HH_MM_SS);
        BigDecimal todayEstimateCommissionAmt = baseMapper.selectEstimateCommissionStatistics(agentId, todayStart, todayEnd);
        // 本月预估
        String firstDayOfMonthStartStr = LocalDateUtil.toLocalDateToString(nowLocalDate.with(TemporalAdjusters.firstDayOfMonth()), Constant.YYYY_MM_DD) + " 00:00:00";
        LocalDateTime firstDayOfMonth = LocalDateUtil.toLocalDateTime(firstDayOfMonthStartStr, Constant.YYYY_MM_DD_HH_MM_SS);
        BigDecimal monthEstimateCommissionAmt = baseMapper.selectEstimateCommissionStatistics(agentId, firstDayOfMonth, todayEnd);

        return new OrderEstimateCommissionVo(todayEstimateCommissionAmt, monthEstimateCommissionAmt);
    }

    private void fixedEnrollNumFullNotify(Long activeId) {
        ActiveVo activeVo = activeApi.getById(activeId).unpack();
        // 报名活动或团购+报名活动 & 固定人数
        if ((activeVo.getActiveType().equals(ActiveTypeEnum.ENROLL.getValue()) || activeVo.getActiveType().equals(ActiveTypeEnum.GROUP_ENROLL.getValue()))
                && activeVo.getStepPriceState().equals(StepPriceStateEnum.NO.getValue())) {

            List<OrderVo> orderList = queryAndFilterValidOrders(activeVo);
            if (orderList.size() >= activeVo.getTotalStock()) {
                for (OrderVo order : orderList) {
                    if (order.getOrderState().equals(OrderStateEnum.CANCEL.getValue())
                            || order.getOrderState().equals(OrderStateEnum.CLOSE.getValue())) {
                        continue;
                    }
                    String activeTitle = order.getActiveTitle();
                    // 发送活动报名结果系统通知
                    NotifyMsgSendDto notifyMsgSendDto = new NotifyMsgSendDto();
                    notifyMsgSendDto.setUserId(order.getUserId());
                    notifyMsgSendDto.setMsgState(NotifyMsgStateEnum.NO_READ.getValue());
                    notifyMsgSendDto.setRoleType(RoleTypeEnum.BUSINESS.getValue());
                    notifyMsgSendDto.setMsgType(NotifyMsgTypeEnum.USER_ACTIVE_ORDER_RESULT.getValue());
                    notifyMsgSendDto.setContent(String.format(MsgConstant.USER_ACTIVE_ORDER_RESULT_FULL, activeTitle));
                    notifyMsgProvider.sendMsg(notifyMsgSendDto);
                }
            }
        }
    }


    private List<OrderVo> queryAndFilterValidOrders(ActiveVo activeVo) {
        OrderDto orderParam = new OrderDto();
        orderParam.setActiveIds(Collections.singletonList(activeVo.getId()));
        // 查询待核销、核销中、已核销、待审核的订单
        // 订单取消和关闭可能发生在活动结束时间之后，需要统计在内
        orderParam.setOrderStates(Arrays.asList(OrderStateEnum.WAIT_VERIFY.getValue(), OrderStateEnum.VERIFYING.getValue(), OrderStateEnum.VERIFIED.getValue(),
                OrderStateEnum.WAIT_AUDIT.getValue(), OrderStateEnum.CLOSE.getValue(), OrderStateEnum.CANCEL.getValue()));
        List<OrderVo> orderList = listByDto(orderParam);

        List<OrderVo> result = new ArrayList<>();
        for (OrderVo orderVo : orderList) {
            if (orderVo.getOrderState().equals(OrderStateEnum.CLOSE.getValue()) && orderVo.getCloseTime().isBefore(activeVo.getEndTime())) {
                continue;
            }
            if (orderVo.getOrderState().equals(OrderStateEnum.CANCEL.getValue()) && orderVo.getCancelTime().isBefore(activeVo.getEndTime())) {
                continue;
            }
            result.add(orderVo);
        }
        return result;
    }
}
